If an integration test uses the org.springframework.boot.test.mock.mockito.SpyBean
annotation to spy a bean, a new Spring Context is created even if it was cached already. In other words, if I have 3 classes (which use the same Spring configuration) for integration tests, the Spring application is started 3 times. Normally, the first context should be cached and reused in the two other test classes.
I imagine that spied components are no longer identical between two tests, so the context is not the same?
This problem occurs with Spring Boot 2.3.2.RELEASE (and 2.4.0 snapshots and M1). No problem with 2.3.1 and previous versions.
You can reproduce this problem with this sample project: https://github.com/jonathanlermitage/spring-mvc-tiny-sample/tree/issue-spybean , run ./mvnw verify
: the application is started 4 times instead of 1 time.
This is a simple REST API with one API that uses one Service. An abstract class is the parent of Integration Test classes (1, 2, etc).
If you remove the spied bean field, or if you set Spring Boot version to 2.3.1 in pom.xml, you will see that the Spring context is cached and reused.
Comment From: krusche
We have the same problem in our project.
When upgrading to Spring Boot 2.3.2, the server application is started several times during integration tests, while in Spring Boot 2.3.1, the server application is only started 3 times (as we test with different profiles).
In our setup on http://github.com/ls1intum/Artemis we have 3 abstract tests that declare the profile and include all SpyBeans.
This essentially prevents us from upgrading at the moment.
Comment From: wilkinsona
Thanks for the report and sample, @jonathanlermitage. Unfortunately, I haven't been able to reproduce the problem. I updated the pom.xml
to use Spring Boot 2.3.2.RELEASE and the application is only started once when running ./mvnw verify
. To double-check, I enabled debug logging for org.springframework.test
and it shows that only a single context has been created:
2020-07-26 17:00:25.494 DEBUG 80340 --- [ main] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@737db7f8 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 70, missCount = 1]
What do I need to do with the sample to reproduce the behaviour that you have described?
Comment From: wilkinsona
@krusche Thanks for the pointer to your app, unfortunately there's a bit too much to it for us to be able to use it to reproduce the problem. If you can provide us with something minimal that we can more easily use to reproduce the problem we can take a look.
Comment From: jonathanlermitage
@wilkinsona Tested on Windows 10 and ubuntu 18.04.
Here is the console output on Windows: console.log
You will see 4 banners and 4 Tomcat startups on different port.
The 3 last startups are very fast in this project, but in in bigger application (with Hibernate entities, Flyway, etc) they will take regular startup time.
Comment From: wilkinsona
@jonathanlermitage Thanks. Only 7 tests were run for me whereas your log shows 9. That led to me looking for differences and I noticed that I'd neglected to switch to the issue-spybean
branch. I've reproduced the problem now.
Comment From: jansu76
Probably not adding much value to the topic anymore, but I am experiencing the same. Upgrading from 2.2.8 to 2.2.9 causes test context creations to grow from 12 to 57 in our builds, and doubles the build time.
Comment From: wilkinsona
Thanks, @jansu76. It's valuable to know that the problem also occurs with 2.2.9. My suspicion is that the fix for https://github.com/spring-projects/spring-boot/issues/20916 is the cause and it was made in 2.2.x.
Comment From: krusche
Thanks for the fix. I'll hope you can release 2.3.3 quickly so that we can upgrade to it 👍