Junit5 Summary

Contents

Junit5 is constructed by 3 modules: Junit-Platform, Junit-Vintage, Junit-Jupiter.

The core package the provide all the unit test functionalities.

This packages is the engine that provides the functionality to execute tests on a platform.

Support for Junit4.

Maven Dependencies are:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.3.0-M1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-api</artifactId>
    <version>5.3.0-M1</version>
    <scope>test</scope>
</dependency>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.22.1</version>
        </plugin>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-failsafe-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
    </plugins>
</build>
  • set up the data for the test
  • different modes
    • Transient Fresh –> new for each
    • Persistence Fresh –> same, but reset
    • Persistence Share –> keep/collect
  • @BeforeEach
  • @AfterEach
  • @BeforeAll
  • @AfterAll

Default instances are created per test cycle/method call. This can be changed at class level.

1
2
3
4
5
@TestInstance(TestInstance.Lifecycle.PER_METHOD) // default
@TestInstance(TestInstance.Lifecycle.PER_CLASS) // @AfterAll, @BeforeAll picked up
class Demo {

}

setUp() and teatDown() methods with annotations.

Nested classes can be used to structure tests. This can improve cohesion and readability.

With @DisplayName("This method ...") a custom name for the method is added to the test report. the annotation can be used on @Test, @BeforeEach and @Nested.

  • Arrange –> Given
  • Act –> When
  • **Assert –> Then
  • test only one logical unit at a time
  • when having multiple depending assertions, they should be coupled
  • be as concrete as possible inside an assertion
1
assertAll("Message", action1(), action2(), ...);

@Disabled("Info why")

There are 3 different types of assumptions.

1
2
3
assumeTrue();
assumeFalse();
assumeThat(Assumption boolean, String message, Executable execute);

consumer<T> –> action<T> supplier<T> –> func<T> function<T, T1> –> func<T, T1>

@Test can also be placed on interfaces.

Repetition for tests can be done with a fixed number of times. Templates are provided to name these tests and add predefined placeholder.

Placeholder:

  • {displayName}
  • {currentRepetition}
  • {totalRepetition}
1
@RepeatedTest(value=5, name="{displayName} run {currentIteration}")

It is possible to inject the a RepetitionInfo into the test function:

1
2
void test(RepetitionInfo repInfo) {
}

Dynamic tests are provided through the test TestFactory. The factory can not be private or static.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
@TestFactory
Stream<DynamicTest> test() {
    return StreamOrigin.stream()
        .map(input -> dynamicTest("name", () -> {
            // test ...
            assertThat(...);
        }));
}

// or

DynamicTest.stream(
    someOtherStream().iterator(),
    iteratorType -> someString, // <- Name
    iteratorType -> assertThat(...)
);

Dynamic container allows to build a tree of nested test functions.

Annotation: @ParameterizedTest

Naming for parameterized tests can be done with placeholders.

  • {index}
  • {arguments}
  • {0} till {n}

These placeholders can be used inside the naming:

1
@ParameterizedTest(name="Test #{index}: id{0}")

To use parameterized tests a maven package must be added:

junit.jupiter-params

Example:

1
2
3
@ParameterizedTest
@ValueSource(longs={...})
void test(long id) {}

It is also possible to inject a TestInfo object and a TestReporter into the methods parameter.

1
2
3
4
5
@ParameterizedTest
@ValueSource(longs={...})
void test(long id, TestInfo info, TestReporter reporter) {
    reporter.publishEntry("id", id);
}