2.12、构造器和方法得依赖注入

在所有之前得JUnit版本,测试构造器或者测试方法是不允许含有参数(至少在标准得Runner实现上是不允许得)。作为JUnit Jupiter得一个大改变来说,构造方法和方法现在可以有参数。构造器和方法允许依赖注入带来了很大得灵活性。

ParameterResolver是为了在运行时动态解析参数的测试扩展定义了API。如果一个测试类得构造器、测试方法或者生命周期方法接收参数,这个参数一定会在被注册得ParameterResolver来解析得。

现在有三个内置得解析器会被自动注册。

  • TestInfoOarameterResolver:如果一个构造器和方法参数是TestInfo类型,TestInfoParameterResolver将提供与当前容器或测试相对应地TestInfo实例。然后可以使用TestInfo来检索关于当前容器或测试的信息,例如显示名称、测试类、测试方法和相关标记。显示名称可以是技术名称,例如测试类或测试方法的名称,也可以是通过@DisplayName配置的自定义名称。

    TestInfo充当JUnit 4中的TestName规则的替代。下面代码演示了如何将TestInfo注入到测试构造器、@BeforeEach方法和@Test方法。

    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:如果方法是用@RepeatedTest@BeforeEach@AfterEach标志,且其参数是RepetitionInfo类型,RepetitionInfoParameterResolver会提供一个RepetitionInfo实例。RepetitionInfo甚至可以用来获取当前对应@RepeatedTest方法地重复测试信息和重复测试地总次数。注意:RepetitionInfoParameterResolver并不会在@RepeatedTest上下文中注册。

  • TestReporterParameterResolver:如果一个构造器和方法参数是TestReporter类型,TestReporterParameterResolver将会提供TestReporter实例。TestReporter可以被用来关于当前测试运行时地额外信息。这些数据会在TestExecutionListenerreportingEntryPublished()方法使用,也可以在IDE或者报告中查看到这些信息。

    JUnit4中使用stoutstderr输出信息,而在JUnit Jupiter使用TestReporter。使用@RunWith(JUnitPlatform.class)将会输出所有信息到stdout。而且,有些ide打印报告条目以输出标准输出,或者在用户界面中显示它们以获得测试结果。

    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);
        }
    
    }
    

    要是想使用其他参数解析器,必须通过@ExtendWith注册适当的扩展显式地启用。

使用RandomParametersExtension作为自定义的ParameterResolver的一个例子。虽然不打算用于生产,但它演示了扩展模型和参数解析过程的简单性和表达性。MyRandomParametersTest展示了如何向@Test方法中注入一个随机值。

@ExtendWith(RandomParametersExtension.class)
class MyRandomParametersTest {

    @Test
    void injectsInteger(@Random int i, @Random int j) {
        assertNotEquals(i, j);
    }

    @Test
    void injectsDouble(@Random double d) {
        assertEquals(0.0, d, 1.0);
    }

}

在真实使用的时候,请参考MockitoExtension源码SpringExtension源码

results matching ""

    No results matching ""