使用 gradle 并行运行 spring boot 测试创建两个应用程序上下文

问题描述

我们在 Netty 上运行了 2 个 Spring Boot 集成测试。

我们使用 gradle 使用标志并行运行测试:org.gradle.parallel=true

测试 1:@SpringBoottest(webEnvironment = WebEnvironment.RANDOM_PORT) 创建 org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext@3736a122

测试 2:@SpringBoottest(webEnvironment = WebEnvironment.MOCK) 创建 org.springframework.boot.web.reactive.context.GenericReactiveWebApplicationContext@45fa13a7

创建了两个应用程序上下文,并将其中一个应用程序上下文随机注入到生产代码中,因此我们有两组 bean。

使用了以下依赖项:

dependencySet(group: 'org.springframework',version: '5.3.5')

dependencySet(group: 'org.springframework.boot',version: '2.4.4')

行为是否正常,因为在一种情况下:使用模拟网络环境而在另一种真实网络环境中使用?

解决方法

当使用 Spring 测试上下文框架时,它将执行 context caching。当使用相同的上下文配置时,它将重用现有的上下文(如果还没有,则启动一个)。如果有新的配置组合(在您的情况下,运行时存在差异,即启动真实服务器或使用模拟环境),它将启动一个新的组合。

来自上述参考指南:

一个 ApplicationContext 可以通过用于加载它的配置参数的组合来唯一标识。因此,配置参数的唯一组合用于生成缓存上下文的密钥。 TestContext 框架使用以下配置参数来构建上下文缓存键:

  • locations(来自@ContextConfiguration
  • classes(来自@ContextConfiguration
  • contextInitializerClasses(来自@ContextConfiguration
  • contextCustomizers(来自 ContextCustomizerFactory)——这包括 @DynamicPropertySource 方法以及来自 Spring Boot 测试支持的各种功能,例如 @MockBean@SpyBean
  • contextLoader(来自@ContextConfiguration
  • parent(来自@ContextHierarchy
  • activeProfiles(来自@ActiveProfiles
  • propertySourceLocations(来自@TestPropertySource
  • propertySourceProperties(来自@TestPropertySource
  • resourceBasePath(来自@WebAppConfiguration

在这种情况下,由于运行时不同,contextCustomizers 存在差异,因此没有可用的缓存上下文,将启动新的上下文。