Java 尽管标记为@Primary,但Spring引导测试未在测试中使用重写bean

Java 尽管标记为@Primary,但Spring引导测试未在测试中使用重写bean,java,spring,spring-boot,junit,spring-boot-test,Java,Spring,Spring Boot,Junit,Spring Boot Test,我们有一个豆公司处理器。 在SpringBootIntegrationTest中,我们希望在这个bean中的方法抛出异常时测试一个异常场景 因此,我们创建了一个覆盖bean TestCompanyProcessor,它扩展了CompanyProcessor。 TestCompanyProcessor标记为@Primary。当我们只运行这个测试类时,测试运行良好,被重写的bean按预期使用 但是这个测试类与其他几个测试类一起运行,每个测试类都标记为@SpringBootTest,我们看到这个测试在

我们有一个豆公司处理器。 在SpringBootIntegrationTest中,我们希望在这个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 annotation时,我们看到了相同的行为。如果您有多个共享相同上下文的Spring测试,您可能会看到这种行为。
Spring正在测试之间缓存测试应用程序上下文。这是默认行为,因为在spring上下文中实例化对象可能需要一些时间

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

有关缓存的更多信息:

DirtiesContext示例:

谢谢,之前我们在许多测试中使用了DirtiesContext,但是他们让测试速度非常慢,但是我们将尝试这种解决方案,只在那些更改了上下文的测试中添加@DirtiesContext,然后看看它是如何运行的。我们遇到了类似的问题。您有多个可供调查的选项。您可以查看是否真的需要完整的Spring上下文。有时您只需要JUnit进行测试,并自己设置必要的依赖项(setter、构造函数注入)。或者在某些情况下,您不需要一个完整的上下文(没有inmemory db可以节省很多时间)并为一组spring测试定义一个更精简的上下文。谢谢您的帮助。不知道为什么,但肮脏的环境没有帮助。似乎根据您的建议,我们不应该为每个测试类加载整个上下文,而应该添加该测试所需的特定bean。这可能有点风险,因为我们正在测试与生产代码设置不同的设置。但如果这是唯一的选择,可能需要这样做。