Introduction
Test constructors or methods were not permitted to contain arguments in any previous JUnit version (at least not with the standard Runner implementations). Both test constructors and methods can now contain parameters, which is one of the primary improvements in JUnit Jupiter. This gives you more freedom and allows you to use Dependency Injection with constructors and methods.
ParameterResolver
ParameterResolver is an API for test extensions that resolve arguments dynamically during runtime. If a test class constructor, a test method, or a lifecycle method accepts a parameter, the parameter must be resolved at runtime by a registered ParameterResolver.
There are three built-in resolvers that are automatically registered at the moment:
- TestInfoParameterResolver
- RepetitionInfoParameterResolver
- TestReporterParameterResolver
TestInfoParameterResolver
The TestInfoParameterResolver will give an instance of TestInfo corresponding to the current container or test as the value for the parameter if a constructor or method parameter is of type TestInfo. The TestInfo may then be used to get information about the current container or test, including the display name, test class, test method, and related tags. A technical name, such as the name of the test class or test method, or a custom name set using @DisplayName, is used as the display name.
TestInfo is a drop-in replacement for the JUnit 4 TestName rule. TestInfo may be injected into a test constructor, @BeforeEach method, and @Test method as seen below.
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
@DisplayName("TestInfo Demo")
class TestInfoDemo {
TestInfoDemo(TestInfo testInfo) {
assertEquals("TestInfo Demo", testInfo.getDisplayName());
}
@BeforeEach
void init(TestInfo testInfo) {
String displayName = testInfo.getDisplayName();
assertTrue(displayName.equals("TEST 1") || displayName.equals("test2()"));
}
@Test
@DisplayName("TEST 1")
@Tag("my-tag")
void test1(TestInfo testInfo) {
assertEquals("TEST 1", testInfo.getDisplayName());
assertTrue(testInfo.getTags().contains("my-tag"));
}
@Test
void test2() {
}
RepetitionInfoParameterResolver
The RepetitionInfoParameterResolver will supply an instance of RepetitionInfo if a method parameter in a @RepeatedTest, @BeforeEach, or @AfterEach method is of type RepetitionInfo. The information about the current repetition and the overall number of repetitions for the relevant @RepeatedTest can then be retrieved using RepetitionInfo. Outside of the context of a @RepeatedTest, however, RepetitionInfoParameterResolver is not registered.
TestReporterParameterResolver
The TestReporterParameterResolver will provide an instance of TestReporter if a constructor or method parameter is of type TestReporter. Additional statistics about the current test run can be published using the TestReporter. The data may be examined in IDEs or included in reports thanks to the reportingEntryPublished() function in a TestExecutionListener.
Where you used to print information to stdout or stderr in JUnit 4, you should use TestReporter in JUnit Jupiter. All reported items will be written to stdout if @RunWith(JUnitPlatform.class) is used. In addition, some IDEs publish report items to stdout or display them as test results in the user interface.
class TestReporterDemo {
@Test
void reportSingleValue(TestReporter testReporter) {
testReporter.publishEntry("a status message");
}
@Test
void reportKeyValuePair(TestReporter testReporter) {
testReporter.publishEntry("a key", "a value");
}
@Test
void reportMultipleKeyValuePairs(TestReporter testReporter) {
Map<String, String> values = new HashMap<>();
values.put("user name", "dk38");
values.put("award year", "1974");
testReporter.publishEntry(values);
}
}