@RunWith(SpringRunner.class) 和 @SpringBootTest 是在使用 Spring Boot 进行单元测试时常用的两个注解,它们分别服务于不同的目的,并协同工作以支持对 Spring 应用程序进行集成测试。下面分别解释这两个注解的作用以及何时可以仅使用 @SpringBootTest。

@RunWith(SpringRunner.class)

作用: @RunWith 是 JUnit 4 中的一个元注解,用于指定测试类应该使用哪个测试运行器(Test Runner)来执行测试方法。SpringRunner 是 Spring 提供的一个特殊的测试运行器,它继承自 JUnit 的 BlockJUnit4ClassRunner,并添加了对 Spring 框架特性的支持。具体来说,SpringRunner 能够:

  1. 管理 Spring 容器的生命周期: 在测试开始前启动一个 Spring 应用上下文(ApplicationContext),并在测试结束后关闭它。

  2. 支持依赖注入(DI): 允许测试类中的字段通过 @Autowired 注解自动注入所需的 Spring Bean。

  3. 处理 Spring 特有的注解: 如 @MockBean、@SpyBean 等,用于模拟或监视测试环境中特定的 Bean。

何时使用: 在编写基于 Spring Boot 的集成测试时,通常需要使用 @RunWith(SpringRunner.class) 以利用上述 Spring 特性。如果你的项目使用的是 JUnit 4,那么这个注解是必不可少的,因为它告诉 JUnit 使用 Spring 提供的测试运行器来执行测试。

@SpringBootTest

  1. 作用: @SpringBootTest 是 Spring Boot 测试框架提供的一个核心注解,用于指示这是一个针对整个 Spring Boot 应用程序的集成测试。它的主要功能包括:

  2. 引导整个应用上下文: 标记为 @SpringBootTest 的测试类会启动一个与实际生产环境相似的 Spring 应用上下文,包含所有配置、组件扫描、自动配置等。

  3. 自动配置测试环境: 根据项目中使用的 Spring Boot starter 和其他依赖,自动配置合适的测试基础设施(如嵌入式数据库、MockMVC、WebTestClient 等)。

与 @RunWith(SpringRunner.class) 协同工作: @SpringBootTest 本身并不直接负责运行测试,而是与 SpringRunner 或其他兼容的测试运行器配合,共同完成 Spring 集成测试的准备工作。

何时仅使用 @SpringBootTest

在某些情况下,可以仅使用 @SpringBootTest 而不需要显式声明 @RunWith(SpringRunner.class),这是因为:

  • 使用 JUnit 5: 如果你的项目已经升级到 JUnit 5,那么不再需要 @RunWith 注解,因为 JUnit 5 引入了扩展模型(Extension Model),通过 @ExtendWith 注解替代了 @RunWith。Spring Boot 测试框架提供了 SpringExtension,它扮演了类似 SpringRunner 的角色。因此,在 JUnit 5 测试类上只需使用 @SpringBootTest,系统会自动识别并使用正确的扩展来执行测试。

      import org.junit.jupiter.api.Test;
      import org.springframework.boot.test.context.SpringBootTest;
    
      @SpringBootTest
      class MySpringBootTest {
          // ...
      }

  • 使用其他测试框架的适配器: 如果你的项目使用的是 TestNG 或其他测试框架,并且有对应的 Spring Boot 支持(如 spring-boot-testng),则可能有相应的适配器类(如 SpringTestNGRunner)代替 SpringRunner。在这种情况下,你可能仅需使用 @SpringBootTest,具体的适配器由测试框架的配置自动处理。

总结

综上所述,@RunWith(SpringRunner.class) 主要用于 JUnit 4 环境中启用 Spring 集成测试支持,而 @SpringBootTest 则定义了测试类是对整个 Spring Boot 应用的集成测试。在使用 JUnit 5 或其他已集成 Spring Boot 支持的测试框架时,通常只需 @SpringBootTest 即可,因为相关的测试运行器或适配器会自动被识别和应用。