Skip to content

devon4j testing

devonfw-core edited this page Dec 16, 2021 · 17 revisions

Testing with devon4j

Testing our applications is one of the most important parts of the development. The devon4j documentation provides detailed information about the testing principles. In addition to that, you can also find information about the topic in the devonfw guide.

In this chapter we are going to focus on showing some test examples, and explain briefly how to start testing our devon4j apps.

MyThaiStar Testing Example

In all the devon4j projects (based on Maven and Spring) we are going to find a dedicated package for testing.

In addition to this, the testing part of the project also has its own resources package, so we are going to be able to configure the application properties or other resources to create specific test scenarios:

MyThaiStar Testing Structure

We should incorporate unit tests as one of our main efforts during development, even considering approaches like test-driven development (TDD).

The tests in our applications should cover a significant amount of functionality. However, in this part of the tutorial, we are going to focus on the test of our devon4j components.

As you have seen in the previous image, each component of our application should have a dedicated package for testing in the test package. Inside each testing package, we will create the related test classes. They should follow this naming convention:

[Component]Test.java

This is because we are going to use Maven to launch the tests of our application and Maven will look for test classes that end with the Test keyword.

Testing under devon4j means, that we already have Spring Test and the devon4j test module available. This also means, that we will find a significant amount of annotations and implementations, which are going to provide us with all the necessary libraries and tools to create our tests in a really simple way.

Focusing on the component tests means, that we are going to test the implementation of the logic layer of our application. Because of this, you can see in our test structure, that our test classes are inside the [component].logic.impl package:

MyThaiStar Testing Structure

If we open one of the test classes we will find something like this:

...

@SpringBootTest(classes = SpringBootApp.class)
public class DishmanagementTest extends ComponentTest {

  @Inject
  private Dishmanagement dishmanagement;

  @Test
  public void findAllDishes() {

    DishSearchCriteriaTo criteria = new DishSearchCriteriaTo();
    List<CategoryEto> categories = new ArrayList<>();
    criteria.setCategories(categories);
    PageRequest pageable = PageRequest.of(0, 100, new Sort(Direction.DESC, "price"));
    criteria.setPageable(pageable);
    Page<DishCto> result = this.dishmanagement.findDishCtos(criteria);
    assertThat(result).isNotNull();
  }

  ...

}
  • @SpringBootTest is the Spring Test annotation to load the context of our application. So we will have the application running like in a real situation.

  • Extending the devon4j test class ComponentTest will inject functionalities like assertions into our test class.

  • Spring Test gives us the option for dependency injection, so we are going to be able to @Inject our components to test them.

  • Finally with the @Test annotation we can declare a test to be executed during the testing process.

Testing our Application

Now that we have brief overview, we are going to add some tests to our JumpTheQueue application.

We have a main component for managing visitors, so we are going to create a dedicated package for testing that component within the com.devonfw.application.jtqj package, called visitormanagement.logic.impl. Inside this new package we are going to add a new test class named VisitormanagementTest.java:

JumpTheQueue Testing Structure
ℹ️

You can see that we already have some test packages in the src/test/java/com.devonfw.application.jtqj.general package. Those tests are from the devon4j archetype and we can use them as a model for further tests in our apps.

In the VisitormanagementTest class we are going to add annotations to run our app in the correct context when executing tests, extend the ComponentTest class to obtain assertions, and inject our visitormanagement component:

...

import javax.inject.Inject;

import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

import com.devonfw.application.jtqj.SpringBootApp;
import com.devonfw.application.jtqj.visitormanagement.logic.api.Visitormanagement;
import com.devonfw.application.jtqj.visitormanagement.logic.api.to.VisitorEto;
import com.devonfw.application.jtqj.visitormanagement.logic.api.to.VisitorSearchCriteriaTo;
import com.devonfw.module.test.common.base.ComponentTest;

@SpringBootTest(classes = SpringBootApp.class)
public class VisitormanagementTest extends ComponentTest {

  @Inject
  private Visitormanagement visitormanagement;
}
ℹ️

Please note, that the class VisitormanagementTest in the code snippet above, extends the class ComponentTest. Make sure, that this is the case in your code too.

Now we can start adding our first test. In JumpTheQueue we have two main functionalities:

  1. Register a visitor, returning an access code.

  2. List the current visitors.

Let’s add tests to check these functionalities:

1. Registration

We are going to create a method with a descriptive name; saveVisitorTest, and we are going to add the @Test annotation to it.

Inside this test, we are going to verify the registration process of our app. To do so, we only need to call the saveVisitor method of the component and provide a VisitorEto object. After the method is called, we are going to check the response of the method, to verify that the expected business logic has been executed correctly:

...

@SpringBootTest(classes = SpringBootApp.class)
public class VisitormanagementTest extends ComponentTest {

  ...

  @Test
  public void saveVisitorTest() {

    VisitorEto visitorEto = new VisitorEto();
    visitorEto.setName("Mary");
    visitorEto.setUsername("mary@mary.com");
    visitorEto.setPhoneNumber("123456789");
    visitorEto.setPassword("test");
    visitorEto.setUserType(false);
    visitorEto.setAcceptedTerms(true);
    visitorEto.setAcceptedCommercial(true);
    VisitorEto visitorEtoResult = this.visitormanagement.saveVisitor(visitorEto);

    assertThat(visitorEtoResult.getId()).isNotNull();

    this.visitormanagement.deleteVisitor(visitorEtoResult.getId());
  }

}
ℹ️

In this saveVisitorTest method, that we give as an example, we can see that there is a deleteVisitor at the end. This would normally only be done, if the tests were run against a production database.If you use a separate database for testing, the last delete is not needed.

ℹ️

Have you noticed, that the mock data of this test is the same data, that we used in previous chapters for the manual verification of our services? Exactly! From now on, this test will allow us to automate the manual verification process.

Now is the time for running the test:

We can do this in several ways, but to simplify the example, just right click the test-method and select Run as > JUnit Test:

JumpTheQueue Running Tests
ℹ️

We can also debug our tests using the Debug As > JUnit Test option.

If you get an error-message saying: No tests found with test runner 'JUnit 5', right-click the test-class, Run As > Run Configurations…​ and then select JUnit 4 as your test runner:

JumpTheQueue Running Tests

The result of the test will be shown in the JUnit tab of Eclipse:

JumpTheQueue Test Results 1

Seems that everything went okay, our register process passes the test. Let’s complete the test checking if the just created user is "Mary".

We can do it simply adding more asserts to check the result object

assertThat(visitorEtoResult.getName()).isEqualTo("Mary");

Now running again the test we should obtain the expected result

JumpTheQueue Test Results 2

2. Finding Visitors

For the second functionality (finding visitors) we can add a new test with a very similar approach. The only difference is that in this case we are going to need to declare a Search Criteria object, that will contain a pageable to recover the first page and the first 100 values.

  @Test
  public void findVisitorsTest() {

    VisitorSearchCriteriaTo criteria = new VisitorSearchCriteriaTo();
    Pageable pageable = PageRequest.of(0, 100);
    criteria.setPageable(pageable);
    Page<VisitorEto> result = this.visitormanagement.findVisitors(criteria);

    assertThat(result).isNotNull();
  }

Use import org.springframework.data.domain to solve the errors. To run both tests (all the tests included in the class) we only need to do right click in any part of the class and select Run As > JUnit Test. All the methods annotated with @Test will be checked.

JumpTheQueue Test Results 3

Extra Functionalities

The devon4j test module provide us with some extra functionalities that we can use to create tests in an easier way.

Extending ComponentTest class we also have available the doSetUp() and doTearDown() methods, that we can use to initialize and release resources in our test classes.

In our JumpTheQueue test class we could declare the visitor object in the doSetUp method, so we can use this resource in several test methods instead of declaring it again and again.

Doing this our test class would be as follows

@SpringBootTest(classes = SpringBootApp.class)
public class VisitormanagementTest extends ComponentTest{

	private VisitorEto visitorEto = new VisitorEto();

	@Inject
	private Visitormanagement visitormanagement;


	@Override
	protected void doSetUp() {
		visitorEto.setName("Mary");
		visitorEto.setUsername("mary@mary.com");
		visitorEto.setPhoneNumber("123456789");
		visitorEto.setPassword("test");
		visitorEto.setUserType(false);
		visitorEto.setAcceptedTerms(true);
		visitorEto.setAcceptedCommercial(true);
	}


  @Test
  public void saveVisitorTest() {

    VisitorEto visitorEtoResult = this.visitormanagement.saveVisitor(visitorEto);

    assertThat(visitorEtoResult.getId()).isNotNull();
    assertThat(visitorEtoResult.getName()).isEqualTo("Mary");

    this.visitormanagement.deleteVisitor(visitorEtoResult.getId());
  }

  @Test
  public void findVisitorsTest() {

    VisitorSearchCriteriaTo criteria = new VisitorSearchCriteriaTo();
    Pageable pageable = PageRequest.of(0, 100);
    criteria.setPageable(pageable);
    Page<VisitorEto> result = this.visitormanagement.findVisitors(criteria);

    assertThat(result).isNotNull();
  }
}

Running the Tests with Maven

We can use Maven to automate the testing of our project. To do so, just open a command prompt with access to Maven (in our devonfw project folder we can simply right click and select Open Devon CMD shell here). Now enter and run:

C:\...\workspaces\main\jump-the-queue\java\jtqj> mvn clean test

Maven will now scan for classes containing the word "Test" and execute all methods annotated with @Test in those classes. The result will look similar to this:

JumpTheQueue Maven Testing

Even though the test we made finished correctly, there are more tests — that devon4j generated automatically — which are going to contain one error related to role assignment. In this tutorial we are only going to implement the visitor side, so we won’t implement role restrictions. We encourage you to add the code for this functionality yourself, after finishing this tutorial.

After we have demonstrated how to create tests in devonfw, we are going to show you how to package and deploy your project in the next chapter.


Next Chapter: Deployment with devonfw