【问题标题】:Running spring boot tests parallelly using gradle create two application contexts使用 gradle 并行运行 Spring Boot 测试会创建两个应用程序上下文
【发布时间】:2021-06-27 13:00:03
【问题描述】:

我们在 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(组:'org.springframework',版本:'5.3.5')

dependencySet(组:'org.springframework.boot',版本:'2.4.4')

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

【问题讨论】:

  • 正如预期的那样,它们有 2 个不同的配置,因此有 2 个实例。如果您使用经典单例来保存ApplicationContext,您将遇到问题。虽然测试并行运行,但它们在同一个 JVM 中运行,因此静态字段只能存在 1 个值,基本上最后一个启动的值将获胜。修复不要使用这样的类。
  • 我们没有任何静态字段,或者您的意思是单格子注入?当我们将 mock 更改为 webEnvironment = WebEnvironment.RANDOM_PORT 时,会创建一个应用程序上下文并在任何地方使用。
  • 正确,因为它是相同的配置。不,我的意思是静态字段。但我怀疑你的代码中有 ApplicationContextHolder 之类的东西。至少从您的描述来看,否则您的问题/问题不清楚。是否创建了 2 个上下文是正确的。
  • @Inject private ApplicationContext applicationContext;
  • 我还是不明白你的问题。这是一个问题吗?不是吗?你的问题是关于这两种情况吗?或者...所以再次是的,您有 2 个上下文,因此您有 2 组所有 bean,这是可以预期的。

标签: java spring spring-boot spring-boot-test


【解决方案1】:

当使用 Spring Test Context Framework 时,它将执行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 存在差异,因此没有可用的缓存上下文,将启动一个新的上下文。

【讨论】:

    猜你喜欢
    • 2017-04-14
    • 1970-01-01
    • 1970-01-01
    • 2019-05-02
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 2016-07-01
    • 1970-01-01
    相关资源
    最近更新 更多