【问题标题】:Spring boot test not using overridden bean in test in spite of marking @Primary尽管标记了@Primary,但Spring引导测试未在测试中使用覆盖的bean
【发布时间】:2021-01-26 22:54:21
【问题描述】:

我们有一个 bean CompanyProcessor。 在spring boot集成测试中,我们想测试这个bean中的方法抛出异常时的异常场景。

因此,我们创建了一个重写 bean TestCompanyProcessor,它扩展了 CompanyProcessor。 TestCompanyProcessor 被标记为@Primary。当我们只运行这个测试类时,测试运行良好并且被覆盖的 bean 按预期使用。

但是这个测试类与其他几个测试类一起运行,每个测试类都标记为@SpringBootTest,我们看到这个测试在第一个实例中失败,因为它没有使用覆盖的bean,而是使用了这个原始bean。我们对失败进行自动重试,最多可重试 3 次。在第二次或第三次重试时,它以某种方式找到了正确的被覆盖的主 bean,并且测试通过了。

有什么原因,为什么它在第一个实例中找到原始 bean,然后在与其他几个测试类一起运行时在随后的重试中找到正确的覆盖 bean。

被覆盖的bean定义如下。

@Primary
@Component
@ConditionalOnExpression("'${test.company.processor}' == 'true'")
class TestCompanyProcessor

在我们的测试课上

@TestPropertySource(properties = {"test.company.processor=true"})
class TestCompanyProcessorTest {

}

附: 当我们使用@Mockbean 注解时,我们看到了相同的行为

【问题讨论】:

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


    【解决方案1】:

    如果您有多个共享相同上下文的 Spring 测试,您可能会看到这种行为。
    Spring 在测试之间缓存您的测试应用程序上下文。这是默认行为,因为在 spring 上下文中对象的实例化可能需要一些时间。

    如果您在不同的测试中有不同的 bean,您应该使用 @DirtiesContext 注释标记更改 ApplicationContext(如 TestCompanyProcessorTest 类)的测试。

    更多关于缓存的信息:
    https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#testing-ctx-management
    DirtiesContext 示例:
    https://www.baeldung.com/spring-dirtiescontext

    【讨论】:

    • 谢谢,早些时候我们在许多测试中都有 DirtiesContext,但它们使测试变得非常慢,但会尝试这种解决方案,将 @DirtiesContext 添加到仅更改上下文的测试中,看看它是如何进行的。跨度>
    • 我们遇到了类似的问题。您有多种选择可以调查。你可以看看你是否真的需要一个完整的 Spring 上下文。有时您只需要 JUnit 进行测试并自己设置必要的依赖项(setter、构造函数注入)。或者在某些情况下,您不需要完整的上下文(没有内存数据库可以节省大量时间)并为一组弹簧测试定义更精简的上下文。
    • 感谢您的帮助。不知道为什么,但 DirtiesContext 没有帮助。根据您的建议,我们似乎不应该为每个测试类加载整个上下文,而只是添加该测试所需的特定 bean。可能有点冒险,因为我们正在测试与生产代码设置不同的设置。但如果这是唯一的选择,可能需要这样做。
    猜你喜欢
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    • 2023-01-25
    • 2016-06-15
    • 2018-04-04
    • 2015-12-14
    • 2018-09-21
    • 2021-03-16
    相关资源
    最近更新 更多