问题
I'm trying to improve the performance of the Spring integration tests of a project I'm working on. We're using Spring + Gradle + JUnit.
With this configuration inside the build.gradle
file:
test {
useJUnit()
setForkEvery(0)
setMaxParallelForks(1)
}
We're able to run all tests in a single JVM. Though I think this is the default behaviour.
But I've been reading about Spring Test Context Caching and with this property in my application-test.yml:
logging:
level:
org:
springframework:
test:
context:
cache: DEBUG
I noticed the following logs for test methods running in the same class
2017-09-05 08:33:11.829 DEBUG 5764 --- [ Test worker] c.DefaultCacheAwareContextLoaderDelegate : Storing ApplicationContext in cache under key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:11.830 DEBUG 5764 --- [ Test worker] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@572e81e7 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 0, missCount = 1]
2017-09-05 08:33:11.849 DEBUG 5764 --- [ Test worker] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:11.850 DEBUG 5764 --- [ Test worker] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@572e81e7 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 1, missCount = 1]
There are many more lines that say Retrieved ApplicationContext from cache with key...
.
For tests methods running in other classes, I noticed similar logs, for example:
2017-09-05 08:33:12.971 DEBUG 10288 --- [ Test worker] c.DefaultCacheAwareContextLoaderDelegate : Storing ApplicationContext in cache under key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:12.971 DEBUG 10288 --- [ Test worker] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@2dad6721 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 0, missCount = 1]
2017-09-05 08:33:13.194 DEBUG 10288 --- [ Test worker] c.DefaultCacheAwareContextLoaderDelegate : Retrieved ApplicationContext from cache with key [THIS HAD SENSITIVE DATA]
2017-09-05 08:33:13.194 DEBUG 10288 --- [ Test worker] org.springframework.test.context.cache : Spring test ApplicationContext cache statistics: [DefaultContextCache@2dad6721 size = 1, maxSize = 32, parentContextCount = 0, hitCount = 1, missCount = 1]
Both classes are annotated equally:
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
@ActiveProfiles({"default", "profile-1", "profile-2"})
public class SomeControllerTest {
// Test methods...
}
And I think it should be possible for test methods in both classes to share the same ApplicationContext
thus decreasing the amount of time the tests last for. But, is it possible to do that? If so, how?
I noticed both ApplicationContext
objects are stored in the cache at around the same time 08:33:11.829
and 08:33:12.971
. Does the Test Runner execute the tests in different threads or something?
回答1:
Your contexts are in fact cached, but you effectively have two different contexts since you use Spring Boot's @MockBean
feature.
The use of @MockBean
causes each ApplicationContext
to have a different unique key under which it is stored in the context cache.
Although this may not be publicly documented anywhere, there is in fact in-line documentation in the implementation of org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory
:
We gather the explicit mock definitions here since they form part of the MergedContextConfiguration key. Different mocks need to have a different key.
I have opened an issue against Spring Boot to have this behavior documented: https://github.com/spring-projects/spring-boot/issues/10182
来源:https://stackoverflow.com/questions/46060579/is-it-possible-to-cache-springs-application-context-between-classes