Junit 5官方文档中文版
  • Introduction
  • 用户指南
    • 概况
      • Junit5是什么?
      • 支持的Java版本
      • 获取帮助
    • 安装
      • 依赖元数据
      • 依赖关系图
      • JUnit Jupiter示例项目
    • 编写测试
      • 注解
      • 标准测试类
      • 显示名称
      • 断言
      • 假设
      • 禁用
      • 标签和过滤
      • 测试实例生命周期
      • 嵌套测试
      • 构造函数和方法的依赖注入
      • 测试接口和默认方法
      • 重复测试
      • 参数化测试
      • 测试模板
      • 动态测试
    • 运行测试
      • IDE支持
      • 构建支持
      • 控制台启动器
      • 使用Junit4运行JUnit Platfrom
      • 配置参数
    • 扩展模型
      • 概述
      • 注册扩展
      • 有条件的测试执行
      • 测试实例后处理
      • 测试生命周期回调
      • 异常处理
      • 为测试模板提供调用上下文
      • 在扩展中维持状态
      • 在扩展中支持的实用程序
      • 用户代码和扩展的相对执行顺序
    • 从Junit4迁移
      • 在Junit Platform上运行JUnit4测试
      • 迁移Tips
      • 受限的JUnit4规则支持
    • 高级主题
      • JUnit Platform Launcher API
    • API演进
      • API版本和状态
      • 实验性API
      • @API工具支持
Powered by GitBook
On this page
  1. 用户指南
  2. 编写测试

构造函数和方法的依赖注入

Previous嵌套测试Next测试接口和默认方法

Last updated 6 years ago

在之前的所有JUnit版本中,测试构造函数或方法都不允许有参数(至少不能使用标准的Runner实现)。作为JUnit Jupiter的主要变化之一,测试构造函数和方法现在都允许有参数。这带来了更大的灵活性,并为构造函数和方法启用依赖注入。

定义了测试扩展的API,希望在运行时动态解析参数。如果测试构造函数或@Test, @TestFactory, @BeforeEach, @AfterEach, @BeforeAll或@AfterAll方法接受参数,则该参数必须在运行时由已注册的ParameterResolver解析。

目前有三个自动注册的内置解析器。

  • 如果方法参数是类型,则TestInfoParameterResolver将提供一个TestInfo的实例,对应当前测试,作为参数的值。然后TestInfo可以用来获取有关当前测试的信息,例如测试的显示名称,测试类,测试方法或关联的标签。显示名称可以是技术名称,例如测试类或测试方法的名称,也可以是通过@DisplayName配置的自定义名称。

    充当JUnit4的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方法中的方法参数类型为,则RepetitionInfoParameterResolver将提供RepetitionInfo的实例。然后可以使用RepetitionInfo获取当前重复信息以及相应的@RepeatedTest的重复总数。但是请注意,RepetitionInfoParameterResolver不在@RepeatedTest的上下文之外注册。请参阅。

  • 如果方法参数的类型是,TestReporterParameterResolver将提供一个TestReporter的实例。TestReporter可用于发布有关当前测试运行的额外数据。数据可以通过TestExecutionListener.reportingEntryPublished()来使用,因此可以被IDE查看或包含在报告中。

    在JUnit Jupiter中,当你需要打印信息时,就像在JUnit4使用stdout或stderr,你应该使用TestReporter。使用@RunWith(JUnitPlatform.class)甚至会将所有报告的条目输出到stdout。

      import java.util.HashMap;
    
      import org.junit.jupiter.api.Test;
      import org.junit.jupiter.api.TestReporter;
    
      class TestReporterDemo {
    
          @Test
          void reportSingleValue(TestReporter testReporter) {
              testReporter.publishEntry("a key", "a value");
          }
    
          @Test
          void reportSeveralValues(TestReporter testReporter) {
              HashMap<String, String> values = new HashMap<>();
              values.put("user name", "dk38");
              values.put("award year", "1974");
    
              testReporter.publishEntry(values);
          }
    
      }

其他参数解析器必须通过@ExtendWith注册适当的扩展来显式启用。

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import com.example.Person;
import com.example.mockito.MockitoExtension;

@ExtendWith(MockitoExtension.class)
class MyMockitoTest {

    @BeforeEach
    void init(@Mock Person person) {
        when(person.getName()).thenReturn("Dilbert");
    }

    @Test
    void simpleTestWithInjectedMock(@Mock Person person) {
        assertEquals("Dilbert", person.getName());
    }

}

查看获取自定义ParameterResolver的示例。虽然不打算生产就绪,它展示了扩展模型和参数解析过程的简单性和表达性。MyMockitoTest演示了如何将Mockito mock注入@BeforeEach和@Test方法。

MockitoExtension
ParameterResolver
TestInfoParameterResolver
TestInfo
TestInfo
RepetitionInfo
TestReporterParameterResolver
TestReporter
重复测试示例