In my project we have a super class for all our tests. This is the signature of that class
@RunWith(SpringRunner.class)
@SpringBootTest(value = {"management.port=0"}, classes = Application.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@ActiveProfiles({"localhost", "test"})
@ContextConfiguration(classes = {Application.class, SomeConfiguration.class})
@Ignore
public abstract class AIntegrationTest {
Where Application.class is our main class, and SomeConfiguration.class it just for some @Bean and other stuff, nothing fancy.
I use gradle, and for running my tests I do:
./gradlew :my-project:test
My problems are:
Since multiple contexts are initialized, it seems that contexts overlap with each other. I know this because one of the symptoms is this exception:
Caused by: org.springframework.jmx.export.UnableToRegisterMBeanException: Unable to register MBean [org.springframework.cloud.context.environment.EnvironmentManager@36408d9e] with key 'environmentManager'; nested exception is javax.management.InstanceAlreadyExistsException: RedeemAway:name=environmentManager,type=EnvironmentManager
Even if I don't care about the multiple contexts being loaded, is my impression that when a test finishes, the next test gets a new context BEFORE the previous one is terminated. I said this because of the overlapping of the exception from above.
Since all the tests share the same JVM, when some beans get registered twice, that exception rises up. From this link:
Context caching
It is said that:
An ApplicationContext can be uniquely identified by the combination of configuration parameters that is used to load it. Consequently, the unique combination of configuration parameters is used to generate a key under which the context is cached. The TestContext framework uses the following configuration parameters to build the context cache key
I understand that, but, I'm wondering how can I achieve that? My goal is to run all my tests over the same JVM and reuse the context with every test.
EDIT on Thu Feb 22
Things I tried:
Really disabling JMX shouldn't help since the excpetion is around the EnvironmentManager, which is from Spring Cloud.
By using the WebEnvironment. RANDOM_PORT you are telling spring boot to start a server on each class instantiation. To avoid this, use a parent class that all testclasses extend from.
We can have multiple application contexts that share a parent-child relationship. A context hierarchy allows multiple child contexts to share beans which reside in the parent context. Each child context can override configuration inherited from the parent context.
The @SpringBootTest annotation tells Spring Boot to look for a main configuration class (one with @SpringBootApplication , for instance) and use that to start a Spring application context.
Empty contextLoads() is a test to verify if the application is able to load Spring context successfully or not.
I found the answer to my problem. Here is well explained:
https://github.com/spring-projects/spring-boot/issues/7174
Basically, if you run a bunch of tests, as soon as one of them gets started, if it uses the annotation @MockBean
it will force Spring to reload the context.
Bonus: you will see the same behavior if your test uses org.mockito.Mock
.
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