本节描述了支持 Spring TestContext 框架的各种类。spring-doc.cn

Spring JUnit 4 运行程序

Spring TestContext 框架通过自定义 runner(在 JUnit 4.12 或更高版本上受支持)。通过使用 或 更短的变体注释测试类,开发人员可以实现基于 JUnit 4 的标准单元和集成测试,以及 同时获得 TestContext 框架的好处,例如支持 加载应用程序上下文, 测试实例的依赖注入, 事务测试 method 执行,依此类推。如果你想将 Spring TestContext 框架与 替代运行程序(例如 JUnit 4 的运行程序)或第三方运行程序 (例如),您可以选择改用 Spring 对 JUnit 规则的支持@RunWith(SpringJUnit4ClassRunner.class)@RunWith(SpringRunner.class)ParameterizedMockitoJUnitRunnerspring-doc.cn

以下代码清单显示了将测试类配置为 使用自定义的 Spring 运行:Runnerspring-doc.cn

@RunWith(SpringRunner.class)
@TestExecutionListeners({})
public class SimpleTest {

	@Test
	public void testMethod() {
		// test logic...
	}
}
@RunWith(SpringRunner::class)
@TestExecutionListeners
class SimpleTest {

	@Test
	fun testMethod() {
		// test logic...
	}
}

在前面的示例中,配置了一个空列表,以 禁用默认侦听器,否则需要 TO 通过 进行配置。@TestExecutionListenersApplicationContext@ContextConfigurationspring-doc.cn

Spring JUnit 4 规则

该软件包提供以下 JUnit 4 个规则(在 JUnit 4.12 或更高版本上受支持):org.springframework.test.context.junit4.rulesspring-doc.cn

SpringClassRule是一个 JUnit,它支持 Spring 的类级功能 TestContext Framework,而是一个支持 Spring TestContext 框架的实例级和方法级功能。TestRuleSpringMethodRuleMethodRulespring-doc.cn

与 相比,Spring 基于规则的 JUnit 支持具有以下优点 独立于任何实现,因此可以是 与现有的替代运行程序(如 JUnit 4 )组合,或 第三方运行程序(例如 )。SpringRunnerorg.junit.runner.RunnerParameterizedMockitoJUnitRunnerspring-doc.cn

要支持 TestContext 框架的全部功能,必须将 a 与 .以下示例显示了正确的方法 要在集成测试中声明这些规则:SpringClassRuleSpringMethodRulespring-doc.cn

// Optionally specify a non-Spring Runner via @RunWith(...)
@ContextConfiguration
public class IntegrationTest {

	@ClassRule
	public static final SpringClassRule springClassRule = new SpringClassRule();

	@Rule
	public final SpringMethodRule springMethodRule = new SpringMethodRule();

	@Test
	public void testMethod() {
		// test logic...
	}
}
// Optionally specify a non-Spring Runner via @RunWith(...)
@ContextConfiguration
class IntegrationTest {

	@Rule
	val springMethodRule = SpringMethodRule()

	@Test
	fun testMethod() {
		// test logic...
	}

	companion object {
		@ClassRule
		val springClassRule = SpringClassRule()
	}
}

JUnit 4 支持类

该软件包提供以下支持 类(在 JUnit 4.12 或更高版本上受支持):org.springframework.test.context.junit4spring-doc.cn

AbstractJUnit4SpringContextTests是一个抽象基测试类,它集成了 Spring TestContext 框架,在 JUnit 4 环境中。扩展 时,可以访问可用于执行显式 bean 查找或测试整个上下文的状态。ApplicationContextAbstractJUnit4SpringContextTestsprotectedapplicationContextspring-doc.cn

AbstractTransactionalJUnit4SpringContextTests是一个抽象的事务扩展,它为 JDBC 添加了一些方便的功能 访问。此类期望在 .当您 extend 中,您可以访问一个实例变量,该变量可用于运行 SQL 语句来查询 数据库。您可以使用此类查询来确认之前和之后的数据库状态 运行与数据库相关的应用程序代码,并且 Spring 确保此类查询在 与应用程序代码相同的事务的范围。当与 一个 ORM 工具,一定要避免误报。 如 JDBC 测试支持中所述,还提供了以下便捷方法: 委托给 中的方法。 此外,还提供了一种针对配置的 SQL 脚本运行 SQL 脚本的方法。AbstractJUnit4SpringContextTestsjavax.sql.DataSourcePlatformTransactionManagerApplicationContextAbstractTransactionalJUnit4SpringContextTestsprotectedjdbcTemplateAbstractTransactionalJUnit4SpringContextTestsJdbcTestUtilsjdbcTemplateAbstractTransactionalJUnit4SpringContextTestsexecuteSqlScript(..)DataSourcespring-doc.cn

这些类便于扩展。如果您不需要您的测试类 要绑定到特定于 Spring 的类层次结构,您可以配置自己的自定义测试 类 using 或 Spring 的 JUnit rules@RunWith(SpringRunner.class)
这些类便于扩展。如果您不需要您的测试类 要绑定到特定于 Spring 的类层次结构,您可以配置自己的自定义测试 类 using 或 Spring 的 JUnit rules@RunWith(SpringRunner.class)

用于 JUnit Jupiter 的 SpringExtension

Spring TestContext 框架提供了与 JUnit Jupiter 测试的完全集成 框架,在 JUnit 5 中引入。通过使用 注释测试类,您可以实现基于 Jupiter 的标准 JUnit 单元 和集成测试,同时获得 TestContext 框架的好处, 例如支持加载应用程序上下文、测试实例的依赖注入、 事务性测试方法执行,等等。@ExtendWith(SpringExtension.class)spring-doc.cn

此外,由于 JUnit Jupiter 中丰富的扩展 API,Spring 提供了 Spring 支持 JUnit 4 和 TestNG 的:spring-doc.cn

下面的代码清单显示了如何配置测试类以将 与 结合使用:SpringExtension@ContextConfigurationspring-doc.cn

// Instructs JUnit Jupiter to extend the test with Spring support.
@ExtendWith(SpringExtension.class)
// Instructs Spring to load an ApplicationContext from TestConfig.class
@ContextConfiguration(classes = TestConfig.class)
class SimpleTests {

	@Test
	void testMethod() {
		// test logic...
	}
}
// Instructs JUnit Jupiter to extend the test with Spring support.
@ExtendWith(SpringExtension::class)
// Instructs Spring to load an ApplicationContext from TestConfig::class
@ContextConfiguration(classes = [TestConfig::class])
class SimpleTests {

	@Test
	fun testMethod() {
		// test logic...
	}
}

由于你也可以使用 JUnit 5 中的注释作为元注释,因此 Spring 提供了 和 组合的注释来简化 测试和 JUnit Jupiter 的配置。@SpringJUnitConfig@SpringJUnitWebConfigApplicationContextspring-doc.cn

以下示例用于减少配置量 在前面的例子中使用:@SpringJUnitConfigspring-doc.cn

// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load an ApplicationContext from TestConfig.class
@SpringJUnitConfig(TestConfig.class)
class SimpleTests {

	@Test
	void testMethod() {
		// test logic...
	}
}
// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load an ApplicationContext from TestConfig.class
@SpringJUnitConfig(TestConfig::class)
class SimpleTests {

	@Test
	fun testMethod() {
		// test logic...
	}
}

同样,以下示例用于创建用于 JUnit Jupiter 的 API:@SpringJUnitWebConfigWebApplicationContextspring-doc.cn

// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load a WebApplicationContext from TestWebConfig.class
@SpringJUnitWebConfig(TestWebConfig.class)
class SimpleWebTests {

	@Test
	void testMethod() {
		// test logic...
	}
}
// Instructs Spring to register the SpringExtension with JUnit
// Jupiter and load a WebApplicationContext from TestWebConfig::class
@SpringJUnitWebConfig(TestWebConfig::class)
class SimpleWebTests {

	@Test
	fun testMethod() {
		// test logic...
	}
}

有关更多详细信息,请参见 Spring JUnit Jupiter Testing Annotations 中的文档。@SpringJUnitConfig@SpringJUnitWebConfigspring-doc.cn

依赖项注入与SpringExtension

它实现了 JUnit Jupiter 的 ParameterResolver 扩展 API,它允许 Spring 为测试提供依赖注入 构造函数、测试方法和测试生命周期回调方法。SpringExtensionspring-doc.cn

具体来说,可以将测试中的依赖项注入到带有 Comments 的测试构造函数和方法中 Spring 的 and 或 JUnit 的 、 、 和其他。SpringExtensionApplicationContext@BeforeTransaction@AfterTransaction@BeforeAll@AfterAll@BeforeEach@AfterEach@Test@RepeatedTest@ParameterizedTestspring-doc.cn

构造函数注入

如果 JUnit Jupiter 测试类的构造函数中的特定参数是类型(或其子类型)或用、、 或 、 或 进行 Meta 注释或元注释,则 Spring 会注入该特定 参数替换为测试的 .ApplicationContext@Autowired@Qualifier@ValueApplicationContextspring-doc.cn

如果 Spring 如果 构造函数被认为是可自动布线的。构造函数被视为 如果满足以下条件之一,则为 autowirable(按优先顺序)。spring-doc.cn

  • 构造函数用 .@Autowiredspring-doc.cn

  • @TestConstructor在测试类上存在或元存在,且属性设置为 。autowireModeALLspring-doc.cn

  • 默认测试构造函数 autowire 模式已更改为 。ALLspring-doc.cn

有关使用和如何更改全局测试构造函数 autowire 模式的详细信息,请参见 @TestConstructor@TestConstructorspring-doc.cn

如果测试类的构造函数被认为是可自动布线的,则 Spring 承担解析构造函数中所有参数的参数的责任。 因此,在 JUnit Jupiter 中注册的其他 API 都无法解析 参数。ParameterResolver

测试类的构造函数注入不能与 JUnit 结合使用 Jupiter 的 support if 用于关闭 测试的 Before 或 After 测试方法。@TestInstance(PER_CLASS)@DirtiesContextApplicationContextspring-doc.cn

原因是指示 JUnit Jupiter 缓存测试 实例。因此,测试实例将保留 对最初从 随后关闭。由于测试类的构造函数只会被调用 一旦在这种情况下,依赖注入将不会再次发生,后续测试 将与来自 closed 的 bean 交互,这可能会导致错误。@TestInstance(PER_CLASS)ApplicationContextApplicationContextspring-doc.cn

与 “before test method” 或 “after test method” 模式一起使用 与 结合使用,必须从 Spring 配置依赖项 通过 field 或 setter 注入提供,以便它们可以在测试之间重新注入 方法调用。@DirtiesContext@TestInstance(PER_CLASS)spring-doc.cn

在下面的示例中, Spring 将 Bean 从加载的 from 注入到构造函数中。OrderServiceApplicationContextTestConfig.classOrderServiceIntegrationTestsspring-doc.cn

@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {

	private final OrderService orderService;

	@Autowired
	OrderServiceIntegrationTests(OrderService orderService) {
		this.orderService = orderService;
	}

	// tests that use the injected OrderService
}
@SpringJUnitConfig(TestConfig::class)
class OrderServiceIntegrationTests @Autowired constructor(private val orderService: OrderService){
	// tests that use the injected OrderService
}

请注意,此功能允许测试依赖项是不可变的,因此是不可变的。finalspring-doc.cn

如果属性是 to (参见 @TestConstructor),我们可以省略上一个例子中构造函数的声明 of,从而产生以下内容。spring.test.constructor.autowire.modeall@Autowiredspring-doc.cn

@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {

	private final OrderService orderService;

	OrderServiceIntegrationTests(OrderService orderService) {
		this.orderService = orderService;
	}

	// tests that use the injected OrderService
}
@SpringJUnitConfig(TestConfig::class)
class OrderServiceIntegrationTests(val orderService:OrderService) {
	// tests that use the injected OrderService
}

方法注入

如果 JUnit Jupiter 测试方法或测试生命周期回调方法中的参数为 类型(或其子类型)或用 、 、 或 、 、 进行 Meta 注释或元注释的 Spring 注入该特定 参数替换为测试的 .ApplicationContext@Autowired@Qualifier@ValueApplicationContextspring-doc.cn

在下面的示例中, Spring 将 from the loaded from 注入到测试方法中:OrderServiceApplicationContextTestConfig.classdeleteOrder()spring-doc.cn

@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {

	@Test
	void deleteOrder(@Autowired OrderService orderService) {
		// use orderService from the test's ApplicationContext
	}
}
@SpringJUnitConfig(TestConfig::class)
class OrderServiceIntegrationTests {

	@Test
	fun deleteOrder(@Autowired orderService: OrderService) {
		// use orderService from the test's ApplicationContext
	}
}

由于 JUnit Jupiter 中支持的健壮性,您还可以 将多个依赖项注入到单个方法中,不仅来自 Spring,而且来自 从 JUnit Jupiter 本身或其他第三方扩展。ParameterResolverspring-doc.cn

以下示例显示了如何同时让 Spring 和 JUnit Jupiter 注入依赖项 同时进入测试方法。placeOrderRepeatedly()spring-doc.cn

@SpringJUnitConfig(TestConfig.class)
class OrderServiceIntegrationTests {

	@RepeatedTest(10)
	void placeOrderRepeatedly(RepetitionInfo repetitionInfo,
			@Autowired OrderService orderService) {

		// use orderService from the test's ApplicationContext
		// and repetitionInfo from JUnit Jupiter
	}
}
@SpringJUnitConfig(TestConfig::class)
class OrderServiceIntegrationTests {

	@RepeatedTest(10)
	fun placeOrderRepeatedly(repetitionInfo:RepetitionInfo, @Autowired orderService:OrderService) {

		// use orderService from the test's ApplicationContext
		// and repetitionInfo from JUnit Jupiter
	}
}

请注意,使用 from JUnit Jupiter 可以让测试方法获得访问权限 到 .@RepeatedTestRepetitionInfospring-doc.cn

@Nestedtest 类配置

自 Spring Framework 5.0 以来, Spring TestContext 框架一直支持在 JUnit Jupiter 中的测试类上使用与测试相关的 Comments;然而,直到Spring 框架 5.3 类级测试配置注释不是 像来自超类一样封闭类。@Nestedspring-doc.cn

Spring Framework 5.3 引入了对继承测试类的一流支持 configuration 的 set,并且此类配置将由 违约。要从默认模式更改为模式,您可以注释 具有 .显式声明将应用于带注释的测试类以及 它的任何子类和嵌套类。因此,您可以注释顶级测试类 替换为 ,这将应用于其所有嵌套测试类 递 归。INHERITOVERRIDE@Nested@NestedTestConfiguration(EnclosingConfiguration.OVERRIDE)@NestedTestConfiguration@NestedTestConfigurationspring-doc.cn

为了允许开发团队将默认值更改为 – 例如, 为了与 Spring Framework 5.0 到 5.2 兼容 – 可以更改默认模式 通过 JVM 系统属性或 classpath 的有关详细信息,请参阅“更改默认封闭配置继承模式”注释。OVERRIDEspring.propertiesspring-doc.cn

尽管下面的 “Hello World” 示例非常简单,但它展示了如何声明 测试继承的顶级类上的通用配置 类。在这个特定示例中,只有配置类是 继承。每个嵌套测试类都提供自己的一组活动配置文件,从而生成一个 distinct (有关详细信息,请参阅 Context Caching)。请参阅支持的注释列表以查看 哪些 Comments 可以在测试类中继承。@NestedTestConfigApplicationContext@Nestedspring-doc.cn

@SpringJUnitConfig(TestConfig.class)
class GreetingServiceTests {

	@Nested
	@ActiveProfiles("lang_en")
	class EnglishGreetings {

		@Test
		void hello(@Autowired GreetingService service) {
			assertThat(service.greetWorld()).isEqualTo("Hello World");
		}
	}

	@Nested
	@ActiveProfiles("lang_de")
	class GermanGreetings {

		@Test
		void hello(@Autowired GreetingService service) {
			assertThat(service.greetWorld()).isEqualTo("Hallo Welt");
		}
	}
}
@SpringJUnitConfig(TestConfig::class)
class GreetingServiceTests {

	@Nested
	@ActiveProfiles("lang_en")
	inner class EnglishGreetings {

		@Test
		fun hello(@Autowired service:GreetingService) {
			assertThat(service.greetWorld()).isEqualTo("Hello World")
		}
	}

	@Nested
	@ActiveProfiles("lang_de")
	inner class GermanGreetings {

		@Test
		fun hello(@Autowired service:GreetingService) {
			assertThat(service.greetWorld()).isEqualTo("Hallo Welt")
		}
	}
}
如果测试类的构造函数被认为是可自动布线的,则 Spring 承担解析构造函数中所有参数的参数的责任。 因此,在 JUnit Jupiter 中注册的其他 API 都无法解析 参数。ParameterResolver

测试类的构造函数注入不能与 JUnit 结合使用 Jupiter 的 support if 用于关闭 测试的 Before 或 After 测试方法。@TestInstance(PER_CLASS)@DirtiesContextApplicationContextspring-doc.cn

原因是指示 JUnit Jupiter 缓存测试 实例。因此,测试实例将保留 对最初从 随后关闭。由于测试类的构造函数只会被调用 一旦在这种情况下,依赖注入将不会再次发生,后续测试 将与来自 closed 的 bean 交互,这可能会导致错误。@TestInstance(PER_CLASS)ApplicationContextApplicationContextspring-doc.cn

与 “before test method” 或 “after test method” 模式一起使用 与 结合使用,必须从 Spring 配置依赖项 通过 field 或 setter 注入提供,以便它们可以在测试之间重新注入 方法调用。@DirtiesContext@TestInstance(PER_CLASS)spring-doc.cn

TestNG 支持类

该软件包提供以下支持 类:org.springframework.test.context.testngspring-doc.cn

AbstractTestNGSpringContextTests是一个抽象基测试类,它集成了 Spring TestContext 框架,在 TestNG 环境。扩展 时,可以访问可用于执行显式 bean 查找或测试整个上下文的状态。ApplicationContextAbstractTestNGSpringContextTestsprotectedapplicationContextspring-doc.cn

AbstractTransactionalTestNGSpringContextTests是一个抽象的事务扩展,它为 JDBC 添加了一些方便的功能 访问。此类期望在 .当您 extend 中,您可以访问一个实例变量,该变量可用于运行 SQL 语句来查询 数据库。您可以使用此类查询来确认之前和之后的数据库状态 运行与数据库相关的应用程序代码,并且 Spring 确保此类查询在 与应用程序代码相同的事务的范围。当与 一个 ORM 工具,一定要避免误报。 如 JDBC 测试支持中所述,还提供了以下便捷方法: 委托给 中的方法。 此外,还提供了一种针对配置的 SQL 脚本运行 SQL 脚本的方法。AbstractTestNGSpringContextTestsjavax.sql.DataSourcePlatformTransactionManagerApplicationContextAbstractTransactionalTestNGSpringContextTestsprotectedjdbcTemplateAbstractTransactionalTestNGSpringContextTestsJdbcTestUtilsjdbcTemplateAbstractTransactionalTestNGSpringContextTestsexecuteSqlScript(..)DataSourcespring-doc.cn

这些类便于扩展。如果您不需要您的测试类 要绑定到特定于 Spring 的类层次结构,您可以配置自己的自定义测试 类 通过使用 、 、 依此类推 和 使用 .查看源代码 of 来了解如何检测测试类的示例。@ContextConfiguration@TestExecutionListenersTestContextManagerAbstractTestNGSpringContextTests
这些类便于扩展。如果您不需要您的测试类 要绑定到特定于 Spring 的类层次结构,您可以配置自己的自定义测试 类 通过使用 、 、 依此类推 和 使用 .查看源代码 of 来了解如何检测测试类的示例。@ContextConfiguration@TestExecutionListenersTestContextManagerAbstractTestNGSpringContextTests