是否可以在类之间缓存Spring的Application Context?

Rub*_*oñi 4 junit spring spring-test gradle applicationcontext

我正在尝试提高我正在研究的项目的Spring集成测试的性能。我们正在使用Spring + Gradle + JUnit。

build.gradle文件中使用以下配置:

test {
    useJUnit()
    setForkEvery(0)
    setMaxParallelForks(1)
}
Run Code Online (Sandbox Code Playgroud)

我们能够在单个JVM中运行所有测试。虽然我认为这是默认行为。

但是我一直在阅读有关Spring Test Context Caching的内容,并且在我的application-test.yml中具有以下属性:

logging:
  level:
    org:
      springframework:
        test:
          context:
            cache: DEBUG
Run Code Online (Sandbox Code Playgroud)

我注意到以下日志用于同一类中运行的测试方法

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]
Run Code Online (Sandbox Code Playgroud)

还有更多的行说Retrieved ApplicationContext from cache with key...

对于在其他类中运行的测试方法,我注意到类似的日志,例如:

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]
Run Code Online (Sandbox Code Playgroud)

这两个类的注释均相同:

test {
    useJUnit()
    setForkEvery(0)
    setMaxParallelForks(1)
}
Run Code Online (Sandbox Code Playgroud)

而且我认为两个类中的测试方法应该可以共享相同的类,ApplicationContext从而减少测试持续的时间。但是,有可能这样做吗?如果是这样,怎么办?

我注意到这两个ApplicationContext对象08:33:11.829和大约在同一时间存储在缓存中08:33:12.971。测试运行器是否以不同的线程或其他方式执行测试?

Sam*_*nen 5

实际上,您的上下文已缓存,但是由于您使用了Spring Boot的@MockBean功能,因此实际上有两个不同的上下文。

@MockBean原因的使用使每个ApplicationContext人都有一个不同的唯一键,将其存储在上下文缓存中。

尽管可能未在任何地方公开记录此文档,但实际上在实现以下方面存在内联文档org.springframework.boot.test.mock.mockito.MockitoContextCustomizerFactory

我们在这里收集了明确的模拟定义,因为它们构成了MergedContextConfiguration键的一部分。不同的模拟需要具有不同的密钥。

我已经针对Spring Boot打开了一个问题来记录此行为:https : //github.com/spring-projects/spring-boot/issues/10182