Spring picks up inner @Configuration
for Test1 from Test2. I need a mocked IService
in Test2 but a real ServiceImpl
in Test1. Also I want to have common TestConfiguration
for all my tests. But I always have mocked IService in both tests. What is wrong?
How I can disable inner configurations picking up for sibling tests?
Here is my code :
ServiceImpl.java:
@Service
public class SeriviveImpl implements IService {
}
TestConfiguration.java:
@Configuration
@ComponentScan
public class TestConfiguration {
// empty
}
Test1.java:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestConfiguration.class})
public class Test1 {
@Autowired
private IService service;
}
Test2.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {Test2.CustomConfiguration.class, TestConfiguration.class})
public class Test2 {
@Autowired
private IService service;
@Configuration
static class CustomConfiguration {
@Bean
IService service() {
return mock(IService.class);
}
}
}
You can filter the inner class from the TestConfiguration @ComponentScan:
@Configuration
@ComponentScan(excludeFilters = {
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,
value = Test2.CustomConfiguration.class)
})
public class TestConfiguration {
// empty
}
This will prevent it being picked up in Test1.
EDIT Or if you have lots of inner configuration you can create your own annotation and filter all these annotated classes from your @ComponentScan:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Configuration
public @interface InnerConfiguration {
}
Then use this annotation on your inner classes instead of @Configuration:
@InnerConfiguration
static class CustomConfiguration {
@Bean
IService service() {
return mock(IService.class);
}
}
and filter these out of your component scan like this:
@Configuration
@ComponentScan(excludeFilters = {
@ComponentScan.Filter(type = FilterType.ANNOTATION,
value = InnerConfiguration.class)
})
public class TestConfiguration {
// empty
}
Since you explicitly use Test2.CustomConfiguration.class
in Test2
's @ContextConfiguration
annotation, you can remove @Configuration
annotation from Test2.CustomConfiguration
and it will not be picked up by @ComponentScan
during Test1
run.
This works because:
To load an ApplicationContext for your tests by using annotated classes (see Java-based container configuration), you can annotate your test class with @ContextConfiguration and configure the classes attribute with an array that contains references to annotated classes.
and
The term “annotated class” can refer to any of the following:
A class annotated with @Configuration.
A component (that is, a class annotated with @Component, @Service, @Repository, or other stereotype annotations).
A JSR-330 compliant class that is annotated with javax.inject annotations.
Any other class that contains @Bean methods.
See https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#testcontext-ctx-management-javaconfig
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With