I have a bunch of tests in my project that are all annotated with @SpringBootTest and therefore load up a SpringBoot context.
Now recently I refactored a Test in which I wanted a smaller scope (it´s about process coverage with camunda) to @RunWith(SpringJUnit4ClassRunner.class). Since this means that no context is loaded automatically I create some beans "manually" with a static inner class configuration. The entire test looks something like this:
@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
Now, this test runs fine when I run it. BUT when I run any other test ( those still annotated with @SpringBootTest), I get issues with when the ApplicationContext is loaded:
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.
Apparently a bean is created when loading the ApplicationContext because the class is annotated with @Component AND the context loader tries to create another bean from my internal configuration.
I cant allow bean-overriding because my mock beans might overwrite the automatically created beans (which they do, I tried).
How do I circumvent this? I want my SpringJUnit4ClassRunner-tests with their internal configurations to not affect my other @SpringBootTest-tests. I already tried making the configuration beans conditional with @ConditionalOnMissingBean but that did not work.
Turns out those inner configuration classes should not be annotated with @Configuration. Removing the annotation makes it so that the manual bean generation still works and the configuration is no longer picked up by the componentScan.