SpringJUnit4ClassRunner 测试的配置与 SpringBootTest 冲突

Posted

技术标签:

【中文标题】SpringJUnit4ClassRunner 测试的配置与 SpringBootTest 冲突【英文标题】:Configuration of SpringJUnit4ClassRunner Test ***es with SpringBootTest 【发布时间】:2020-01-02 11:22:06 【问题描述】:

我的项目中有一堆测试,它们都用 @SpringBootTest 注释,因此加载了 SpringBoot 上下文。

现在我最近将一个测试重构为@RunWith(SpringJUnit4ClassRunner.class),其中我想要一个更小的范围(它是关于 camunda 的进程覆盖率)。 由于这意味着不会自动加载上下文,因此我使用静态内部类配置“手动”创建了一些 bean。整个测试看起来像这样:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = 
        ExternalConfiguration.class, MyTest.InternalConfiguration.class
)
public class MyTest

    @Autowired
    private SomeBean someInternalBean;

    @Configuration
    public static class InternalConfiguration

        @Bean
        SomeBean someInternalBean() 
            return mock(SomeBean .class);
        

    
    //Tests

现在,当我运行这个测试时,它运行良好。但是当我运行任何其他测试(那些仍然用 @SpringBootTest 注释的测试)时,我在加载 ApplicationContext 时遇到问题:

The bean 'someInternalBean', defined in class path resource [.../MyTest$InternalConfiguration.class], could not be registered. A bean with that name has already been defined in file [.../SomeBean.class] and overriding is disabled.

显然,在加载 ApplicationContext 时会创建一个 bean,因为该类是用 @Component 注释的,并且上下文加载器试图从我的内部配置中创建另一个 bean。

我不能允许 bean 覆盖,因为我的模拟 bean 可能会覆盖自动创建的 bean(他们这样做,我试过了)。

我该如何规避这个问题?我希望我的 SpringJUnit4ClassRunner 测试及其内部配置不会影响我的其他 @SpringBootTest 测试。我已经尝试使用 @ConditionalOnMissingBean 使配置 bean 有条件,但这不起作用。

【问题讨论】:

【参考方案1】:

原来那些内部配置类不应该用@Configuration注解。删除注释后,手动生成 bean 仍然有效,并且 componentScan 不再拾取配置。

【讨论】:

以上是关于SpringJUnit4ClassRunner 测试的配置与 SpringBootTest 冲突的主要内容,如果未能解决你的问题,请参考以下文章

Java 8.Spring--整合Junit测试

@RunWith(SpringJUnit4ClassRunner.class)报错

如何使用参数化运行 JUnit SpringJUnit4ClassRunner?

测试后 SpringJUnit4ClassRunner 是不是仍然不能可靠地调用 DisposableBean.destroy

SpringJUnit4ClassRunner 与 JUnit 测试套件错误

SpringJUnit4ClassRunner 和 SpringRunner 有啥区别