在 Spring Boot 测试中重用昂贵的 bean

Posted

技术标签:

【中文标题】在 Spring Boot 测试中重用昂贵的 bean【英文标题】:Reusing expensive beans in Spring Boot Tests 【发布时间】:2020-11-25 20:32:29 【问题描述】:

我正在尝试提高 Spring Boot 中 medium 测试的性能。

我正在使用Spring Boot - testcontainers 库。

对于单独的测试,这非常有效,只需添加一些注释,我就可以访问 kafka、zookeeper 和 schema-registry。这些是完整的服务,因此启动一切需要几秒钟,所有设置总共需要大约 40 秒。该测试准确地重新创建了一个真实的部署,非常简单。

如果它只发生一次就好了,但每次创建 Spring 上下文时都会发生。这意味着使用 @MockBean 的每个测试都会产生 40 秒的成本。

我尝试重构为单个 TestConfiguration 类并引用它。我已经研究过使用 ContextHierarchy,但我认为这意味着我将失去所有 Spring Boot 的细节,我需要重新创建上下文(这意味着它看起来与生产应用程序创建的上下文不完全相同)。

有没有更好的方法来做到这一点?

【问题讨论】:

为每个测试启动一个新的 ApplicationContext 是设计使然。它可以防止奇怪的副作用影响无关的测试。比如,如果一个失败的测试在 kafka 中留下了一条消息,会发生什么?它将开始无法通过其他测试。这将使查明错误的来源变得更加困难。 我最近发表了一篇关于上下文缓存机制的文章,对你有帮助rieckpil.de/…。为了进一步减少本地构建时间,您还可以使用 Testcontainers 重用容器:rieckpil.de/… 【参考方案1】:

Spring 框架已经处理了这种情况。

有一个为测试类/类缓存应用程序上下文的概念。 请参阅documentation。

文档中的几行:

Spring TestContext 框架将应用程序上下文存储在一个 静态缓存。这意味着上下文实际上存储在一个 静态变量。换句话说,如果测试在不同的进程中运行, 在每次测试执行之间清除静态缓存,这 有效地禁用了缓存机制。

所以本质上,您需要以在所需测试用例中使用缓存上下文的方式来构建代码或上下文配置。

但要明智地使用此功能,如果没有正确考虑,可能会导致不良副作用

【讨论】:

以上是关于在 Spring Boot 测试中重用昂贵的 bean的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot测试类能否重用应用程序上下文以加快测试运行速度?

如何在 Spring Boot REST 应用程序中重用类?

使用 Spring Security OAuth 时 Spring Boot Reactive WebClient “serverWebExchange must be null”

Spring Boot 项目“org.springframework.beans.factory.BeanCreationException:创建名为“entityManagerFactory”的be

spring boot 启动的时候required a bean of type 'XXX' not be

spring boot项目启动报(No session repository could be auto-configured, check your configuration (session s