java - Spring 测试上下文最佳实践

标签 java spring design-patterns spring-boot spring-test

我正试图用集成测试覆盖一个巨大的 Spring Boot 应用程序。应用程序中有很多 Spring bean。加载 Spring 上下文需要一段时间。

所以我想知道-

  • Spring 是否足够聪明,可以在位于不同类的多个集成测试之间共享相同的上下文?我的意思是避免为每个测试类初始化重量级上下文。
  • 当测试 1、2、4 使用 TestContextOne 而测试 3,5 使用 TestContextTwo 时会发生什么? Spring 是否按 1、2、4、3、5 顺序启动它们?还是 Spring 会在内存中保留两个上下文?

P.S. 换句话说,是对所有集成测试使用单个“完整”Spring 上下文的常见做法,而不是为每个测试编写单独的上下文测试?

最佳答案

spring 框架为测试应用程序提供的主要功能之一是上下文缓存机制,可以避免您提到的负载开销。 spring 文档说:

Once the TestContext framework loads an ApplicationContext (or WebApplicationContext) for a test, that context will be cached and reused for all subsequent tests that declare the same unique context configuration within the same test suite.

考虑到这一点,您必须了解缓存机制如何工作以确定构建测试的最佳策略。这里的问题是:当 spring 缓存上下文时,它使用什么键将这个上下文存储在内存中?。根据文档, key 基于容器的一些参数:

An ApplicationContext can be uniquely identified by the combination of configuration parameters that are used to load it. Consequently, the unique combination of configuration parameters are 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:

locations (from @ContextConfiguration)
classes (from @ContextConfiguration)
contextInitializerClasses (from @ContextConfiguration)
contextCustomizers (from ContextCustomizerFactory)
contextLoader (from @ContextConfiguration)
parent (from @ContextHierarchy)
activeProfiles (from @ActiveProfiles)
propertySourceLocations (from @TestPropertySource)
propertySourceProperties (from @TestPropertySource)
resourceBasePath (from @WebAppConfiguration)

根据这些信息,我可能会建议您最好的做法是组织您的测试,使它们使用相同的上下文参数集(即相同的缓存键)以从缓存机制中受益并避免另一个上下文被加载。 Spring文档也给出了一个例子:

..., if TestClassA specifies {"app-config.xml", "test-config.xml"} for the locations (or value) attribute of @ContextConfiguration, the TestContext framework will load the corresponding ApplicationContext and store it in a static context cache under a key that is based solely on those locations. So if TestClassB also defines {"app-config.xml", "test-config.xml"} for its locations (either explicitly or implicitly through inheritance) but does not define @WebAppConfiguration, a different ContextLoader, different active profiles, different context initializers, different test property sources, or a different parent context, then the same ApplicationContext will be shared by both test classes. This means that the setup cost for loading an application context is incurred only once (per test suite), and subsequent test execution is much faster.

关于java - Spring 测试上下文最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42912616/

相关文章:

java - 尝试创建新的数据库 Play Framework ebean mysql 时出现错误

java - 使用 aes 从 java 解密文件中的额外字符

java - Spring Boot 2 JasperReportsMultiFormatView

c# - 相似函数重构模式

java - 创建文件并返回枚举作为结果的模式或约定

java - 无法理解这个 Java Stream+Generics 示例

Java - 创建一个 RPG 对话框

reactjs - 为什么迁移到 https 会中断客户端和服务器之间的通信?

java - Spring Boot - 从依赖 jar 加载 application.properties/yml

design-patterns - 空对象模式是否会使调试变得更加复杂?