Excluding Configuration in Spring boot test
First, I don't like the idea of putting a config class in another class. I don't know if that is frenquently made, I'm kinda new to Spring. But here is what I would do :
First config file :
@Configuration
@Import(MyConfiguration.class)
public class MyTestConfiguration {
@Bean
@Primary // added to let know on @Autowired to use this one instead of the one in first MyConfiguration.class
public A beanA() {
return mock(A.class);
}
}
Second config file :
@Configuration
@Import(MyConfiguration.class)
public class MyOtherTestConfiguration {
@Bean
public B beanB() {
return new B()
}
}
I'm not familiar with @TestConfiguration
. That's why i'm using @Configuration
.
First test class :
package com.example;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyTestConfiguration.class)
public class SpringConfigurationTest {
}
Second test class :
package com.example.sub;
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyOtherTestConfiguration.class)
public class AnotherSpringConfigurationTest {
}
hotzst
Professionally I am working for the Swiss based company Netcetera mainly in a capacity of technical advisor with the occasional opportunity to produce some code myself. To be able to do that one has to keep abreast with the technical developments. For that reason, among others, I am programming the game OpenPatrician, which is a Java based reimplementation of "The Patrician III" using JavaFX for the UI and Spring in the background.
Updated on June 23, 2022Comments
-
hotzst almost 2 years
I have the following setup in a maven project. Configuration class for the productive code:
package com.example; @Configuration public class MyConfiguration { @Bean public A beanA() { return new A(); } ... }
Then I have one test, that has an internal
Configuration
:package com.example; @RunWith(SpringRunner.class) @ContextConfiguration(classes = {MyConfiguration.class, SpringConfigurationTest.MyTestConfiguration.class}) public class SpringConfigurationTest { @TestConfiguration static class MyTestConfiguration { @Bean @Primary public A beanA() { return mock(A.class); } } }
The tests in this class work fine. Then I do have another Test class in sub package:
package com.example.sub; @RunWith(SpringRunner.class) @ContextConfiguration(classes = {MyConfiguration.class, AnotherSpringConfigurationTest.MyTestConfiguration.class}) public class AnotherSpringConfigurationTest { @TestConfiguration static class MyTestConfiguration { @Bean public B beanB() { return new B() } } }
When running tests in this class the test configuration from
SpringConfigurationTest.MyTestConfiguration
is also included. My guess the reason for this is the inclusion ofMyConfiguration
which lies in the root directory. The effect is that inAnotherSpringConfigurationTest
the beanA
is mocked instead of a real instance.How can I avoid that configuration classes inside other tests are 'leaked' into other tests?
I have seen Spring-boot default profile for integration tests which uses Spring profiles in Spring Boot 1.4.1, while I am using Spring Boot 2.0.1. Though I am sure it could be done.
Another approach I could think of would be to use component scanning to pick up the contexts and exclude all those that I do not want, but that is a bit cumbersome, as I would much prefer an approach where I define what I want to use instead of what should not be used.
Is there an easy and elegant solution with Spring Boot 2 to avoid conflicting context configurations?
-
hotzst almost 6 yearsI had the configurations in a separate file, but that did not change a thing.
-
GabLeg almost 6 yearsIt's not that it will not work, I just don't like the concept.
-
hotzst almost 6 yearsTried your approach with having one configuration and bringing in the others with
@Import
. Did not work, I assume because Spring boot just does not work that way, but takes the configuration as root to scan for further beans, which configurations are one kind of. -
GabLeg almost 6 yearsI tried the setup you provided and it worked with no problem. So I don't think the problem is on your test setup.