TestContext Framework Support Classes

本部分描述支持 Spring TestContext Framework 的各种类。

This section describes the various classes that support the Spring TestContext Framework.

Spring JUnit 4 Runner

Spring TestContext框架通过自定义运行器(在JUnit 4.12或更高版本上受支持)与JUnit 4完全集成。通过使用`@RunWith(SpringJUnit4ClassRunner.class)或更短的@RunWith(SpringRunner.class)变体注解测试类,开发人员可以实现基于JUnit 4的标准单元和集成测试,同时充分利用TestContext框架的优势,例如支持加载应用程序上下文、测试实例的依赖项注入、事务测试方法执行等。如果你想将Spring TestContext Framework与替代运行器(例如JUnit 4的`Parameterized`运行器)或第三方运行器(例如`MockitoJUnitRunner)一起使用,你可以选择使用Spring’s support for JUnit rules

The Spring TestContext Framework offers full integration with JUnit 4 through a custom runner (supported on JUnit 4.12 or higher). By annotating test classes with @RunWith(SpringJUnit4ClassRunner.class) or the shorter @RunWith(SpringRunner.class) variant, developers can implement standard JUnit 4-based unit and integration tests and simultaneously reap the benefits of the TestContext framework, such as support for loading application contexts, dependency injection of test instances, transactional test method execution, and so on. If you want to use the Spring TestContext Framework with an alternative runner (such as JUnit 4’s Parameterized runner) or third-party runners (such as the MockitoJUnitRunner), you can, optionally, use Spring’s support for JUnit rules instead.

以下代码清单显示了使用自定义 Spring “Runner” 运行测试类的最小要求:

The following code listing shows the minimal requirements for configuring a test class to run with the custom Spring Runner:

  • Java

  • Kotlin

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

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

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

在上述示例中,“@TestExecutionListeners” 配置了一个空列表,以禁用默认侦听器,否则默认侦听器将要求通过 “@ContextConfiguration” 配置 “ApplicationContext”。

In the preceding example, @TestExecutionListeners is configured with an empty list, to disable the default listeners, which otherwise would require an ApplicationContext to be configured through @ContextConfiguration.

Spring JUnit 4 Rules

“org.springframework.test.context.junit4.rules” 包提供以下 JUnit 4 规则(在 JUnit 4.12 或更高版本上受支持):

The org.springframework.test.context.junit4.rules package provides the following JUnit 4 rules (supported on JUnit 4.12 or higher):

  • SpringClassRule

  • SpringMethodRule

“SpringClassRule” 是 JUnit “TestRule”,支持 Spring TestContext Framework 的类级特性,而 “SpringMethodRule” 是 JUnit “MethodRule”,支持 Spring TestContext Framework 的实例级和方法级特性。

SpringClassRule is a JUnit TestRule that supports class-level features of the Spring TestContext Framework, whereas SpringMethodRule is a JUnit MethodRule that supports instance-level and method-level features of the Spring TestContext Framework.

与 “SpringRunner” 相比,Spring 基于规则的 JUnit 支持具有独立于任何 “org.junit.runner.Runner” 实现的优势,因此可以与现有的其他运行器(例如 JUnit 4 的 “Parameterized”)或第三方运行器(例如 “MockitoJUnitRunner”)结合使用。

In contrast to the SpringRunner, Spring’s rule-based JUnit support has the advantage of being independent of any org.junit.runner.Runner implementation and can, therefore, be combined with existing alternative runners (such as JUnit 4’s Parameterized) or third-party runners (such as the MockitoJUnitRunner).

为了支持 TestContext 框架的全部功能,你必须将 “SpringClassRule” 与 “SpringMethodRule” 结合使用。以下示例显示在集成测试中声明这些规则的正确方法:

To support the full functionality of the TestContext framework, you must combine a SpringClassRule with a SpringMethodRule. The following example shows the proper way to declare these rules in an integration test:

  • Java

  • Kotlin

// 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 Support Classes

“org.springframework.test.context.junit4” 包为基于 JUnit 4 的测试用例提供以下支持类(在 JUnit 4.12 或更高版本上受支持):

The org.springframework.test.context.junit4 package provides the following support classes for JUnit 4-based test cases (supported on JUnit 4.12 or higher):

  • AbstractJUnit4SpringContextTests

  • AbstractTransactionalJUnit4SpringContextTests

“AbstractJUnit4SpringContextTests” 是一个抽象基础测试类,它在 JUnit 4 环境中集成了具有显式 “ApplicationContext” 测试支持的 Spring TestContext Framework。当你扩展 “AbstractJUnit4SpringContextTests” 时,你可以访问一个 “protected” “applicationContext” 实例变量,可以使用该变量执行显式 Bean 查找或测试上下文的整体状态。

AbstractJUnit4SpringContextTests is an abstract base test class that integrates the Spring TestContext Framework with explicit ApplicationContext testing support in a JUnit 4 environment. When you extend AbstractJUnit4SpringContextTests, you can access a protected applicationContext instance variable that you can use to perform explicit bean lookups or to test the state of the context as a whole.

`AbstractTransactionalJUnit4SpringContextTests`是`AbstractJUnit4SpringContextTests`的抽象事务扩展,为JDBC访问添加了一些便捷功能。此类期望在`ApplicationContext`中定义`javax.sql.DataSource`bean和`PlatformTransactionManager`bean。在扩展`AbstractTransactionalJUnit4SpringContextTests`时,你可以访问`protected``jdbcTemplate`实例变量,可使用它来运行查询数据库的SQL语句。你可以使用此类查询来确认在运行与数据库相关的应用程序代码之前和之后的状态,并且Spring会确保此类查询在与应用程序代码相同的事务范围内运行。在与ORM工具结合使用时,请务必避免使用false positives。如JDBC Testing Support中所述,`AbstractTransactionalJUnit4SpringContextTests`还提供了一些便利方法,通过使用上述`jdbcTemplate`来委托给`JdbcTestUtils`中的方法。此外,`AbstractTransactionalJUnit4SpringContextTests`提供了一个`executeSqlScript(..)`方法,用于针对配置的`DataSource`运行SQL脚本。

AbstractTransactionalJUnit4SpringContextTests is an abstract transactional extension of AbstractJUnit4SpringContextTests that adds some convenience functionality for JDBC access. This class expects a javax.sql.DataSource bean and a PlatformTransactionManager bean to be defined in the ApplicationContext. When you extend AbstractTransactionalJUnit4SpringContextTests, you can access a protected jdbcTemplate instance variable that you can use to run SQL statements to query the database. You can use such queries to confirm database state both before and after running database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the application code. When used in conjunction with an ORM tool, be sure to avoid false positives. As mentioned in JDBC Testing Support, AbstractTransactionalJUnit4SpringContextTests also provides convenience methods that delegate to methods in JdbcTestUtils by using the aforementioned jdbcTemplate. Furthermore, AbstractTransactionalJUnit4SpringContextTests provides an executeSqlScript(..) method for running SQL scripts against the configured DataSource.

这些类可方便于扩展。如果您不希望测试类绑定到 Spring 特定的类层次结构,则可以使用 @RunWith(SpringRunner.class)Spring’s JUnit rules 配置自己的自定义测试类。

These classes are a convenience for extension. If you do not want your test classes to be tied to a Spring-specific class hierarchy, you can configure your own custom test classes by using @RunWith(SpringRunner.class) or Spring’s JUnit rules .

SpringExtension for JUnit Jupiter

Spring TestContext Framework 提供与 JUnit 5 中引入的 JUnit Jupiter 测试框架的完全集成。通过用 “@ExtendWith(SpringExtension.class)” 对测试类进行注释,你可以实现基于 JUnit Jupiter 的标准单元和集成测试,同时享受 TestContext 框架带来的好处,例如加载应用程序上下文、测试实例的依赖注入、事务性测试方法执行等的支持。

The Spring TestContext Framework offers full integration with the JUnit Jupiter testing framework, introduced in JUnit 5. By annotating test classes with @ExtendWith(SpringExtension.class), you can implement standard JUnit Jupiter-based unit and integration tests and simultaneously reap the benefits of the TestContext framework, such as support for loading application contexts, dependency injection of test instances, transactional test method execution, and so on.

此外,由于 JUnit Jupiter 中丰富的扩展 API,Spring 提供了以下特性,超出了 Spring 对 JUnit 4 和 TestNG 支持的特性集:

Furthermore, thanks to the rich extension API in JUnit Jupiter, Spring provides the following features above and beyond the feature set that Spring supports for JUnit 4 and TestNG:

以下代码清单展示了如何配置一个测试类以将`SpringExtension`与 @ContextConfiguration 结合使用:

The following code listing shows how to configure a test class to use the SpringExtension in conjunction with @ContextConfiguration:

  • Java

  • Kotlin

// 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 提供了`@SpringJUnitConfig` 和 @SpringJUnitWebConfig 复合注解来简化测试 ApplicationContext 和 JUnit Jupiter 的配置。

Since you can also use annotations in JUnit 5 as meta-annotations, Spring provides the @SpringJUnitConfig and @SpringJUnitWebConfig composed annotations to simplify the configuration of the test ApplicationContext and JUnit Jupiter.

以下示例使用 @SpringJUnitConfig 来减少前一个示例中使用的配置量:

The following example uses @SpringJUnitConfig to reduce the amount of configuration used in the previous example:

  • Java

  • Kotlin

// 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...
	}
}

同样,以下示例使用 @SpringJUnitWebConfig 为 JUnit Jupiter 创建一个`WebApplicationContext`:

Similarly, the following example uses @SpringJUnitWebConfig to create a WebApplicationContext for use with JUnit Jupiter:

  • Java

  • Kotlin

// 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@SpringJUnitWebConfig 的文档,以了解详细信息。

See the documentation for @SpringJUnitConfig and @SpringJUnitWebConfig in Spring JUnit Jupiter Testing Annotations for further details.

Dependency Injection with the SpringExtension

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

The SpringExtension implements the ParameterResolver extension API from JUnit Jupiter, which lets Spring provide dependency injection for test constructors, test methods, and test lifecycle callback methods.

具体来说,SpringExtension 可以从测试的`ApplicationContext` 中向使用 Spring 的 @BeforeTransaction@AfterTransaction 或 JUnit 的 @BeforeAll@AfterAll@BeforeEach@AfterEach@Test@RepeatedTest@ParameterizedTest 等进行注释或元注释的测试构造函数和方法注入依赖项。

Specifically, the SpringExtension can inject dependencies from the test’s ApplicationContext into test constructors and methods that are annotated with Spring’s @BeforeTransaction and @AfterTransaction or JUnit’s @BeforeAll, @AfterAll, @BeforeEach, @AfterEach, @Test, @RepeatedTest, @ParameterizedTest, and others.

Constructor Injection

如果 JUnit Jupiter 测试类的构造函数中的特定参数是类型为 ApplicationContext(或其子类型)的或者使用 @Autowired@Qualifier@Value 进行了注释或元注释,Spring 将使用测试的 ApplicationContext 中对应的 bean 或值注入该特定参数的值。

If a specific parameter in a constructor for a JUnit Jupiter test class is of type ApplicationContext (or a sub-type thereof) or is annotated or meta-annotated with @Autowired, @Qualifier, or @Value, Spring injects the value for that specific parameter with the corresponding bean or value from the test’s ApplicationContext.

如果构造函数被认为是 autowirable 的,还可以将 Spring 配置为自动注入测试类构造函数的所有参数。如果满足以下条件之一(按优先顺序),则构造函数被认为是可自动注入的。

Spring can also be configured to autowire all arguments for a test class constructor if the constructor is considered to be autowirable. A constructor is considered to be autowirable if one of the following conditions is met (in order of precedence).

  • The constructor is annotated with @Autowired.

  • @TestConstructor is present or meta-present on the test class with the autowireMode attribute set to ALL.

  • The default test constructor autowire mode has been changed to ALL.

请参阅@TestConstructor以了解`@TestConstructor`的使用详情以及如何更改全局_test constructor autowire mode_。

See @TestConstructor for details on the use of @TestConstructor and how to change the global test constructor autowire mode.

如果测试类的构造函数被视为 autowirable,Spring 会负责解析构造函数中所有参数的参数。因此,用 JUnit Jupiter 注册的其他 ParameterResolver 无法解析此类构造函数的参数。

If the constructor for a test class is considered to be autowirable, Spring assumes the responsibility for resolving arguments for all parameters in the constructor. Consequently, no other ParameterResolver registered with JUnit Jupiter can resolve parameters for such a constructor.

如果使用 @DirtiesContext 在测试方法之前或之后关闭测试的 ApplicationContext,则测试类的构造函数注入不得与 JUnit Jupiter 的 @TestInstance(PER_CLASS) 支持一起使用。

Constructor injection for test classes must not be used in conjunction with JUnit Jupiter’s @TestInstance(PER_CLASS) support if @DirtiesContext is used to close the test’s ApplicationContext before or after test methods.

原因是 @TestInstance(PER_CLASS) 指示 JUnit Jupiter 在测试方法调用之间缓存测试实例。因此,测试实例将保留对最初从已随后关闭的 ApplicationContext 注入的 bean 的引用。由于在这种情况下测试类的构造函数只会调用一次,因此依赖项注入不会再次发生,并且后续测试将与已关闭的 ApplicationContext 中的 bean 交互,这可能会导致错误。

The reason is that @TestInstance(PER_CLASS) instructs JUnit Jupiter to cache the test instance between test method invocations. Consequently, the test instance will retain references to beans that were originally injected from an ApplicationContext that has been subsequently closed. Since the constructor for the test class will only be invoked once in such scenarios, dependency injection will not occur again, and subsequent tests will interact with beans from the closed ApplicationContext which may result in errors.

要在“测试方法之前”或“测试方法之后”模式下与 @TestInstance(PER_CLASS) 结合使用 @DirtiesContext,必须配置 Spring 的依赖项,以便通过字段或 setter 注入提供,这样它们才能在测试方法调用之间重新注入。

To use @DirtiesContext with "before test method" or "after test method" modes in conjunction with @TestInstance(PER_CLASS), one must configure dependencies from Spring to be supplied via field or setter injection so that they can be re-injected between test method invocations.

在以下示例中,Spring 将从 TestConfig.class 加载的 ApplicationContext 中的 OrderService bean 注入到 OrderServiceIntegrationTests 构造函数中。

In the following example, Spring injects the OrderService bean from the ApplicationContext loaded from TestConfig.class into the OrderServiceIntegrationTests constructor.

  • Java

  • Kotlin

@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
}

请注意,此功能让测试依赖项成为 final 的,因此是不可变的。

Note that this feature lets test dependencies be final and therefore immutable.

如果`spring.test.constructor.autowire.mode`属性设置为`all`(请参阅@TestConstructor),则可以省略对前一个示例中构造函数上的`@Autowired`的声明,从而导致以下现象。

If the spring.test.constructor.autowire.mode property is to all (see @TestConstructor), we can omit the declaration of @Autowired on the constructor in the previous example, resulting in the following.

  • Java

  • Kotlin

@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
}

Method Injection

如果 JUnit Jupiter 测试方法或测试生命周期回调方法中的参数是类型 ApplicationContext(或其子类型)的或者使用 @Autowired@Qualifier@Value 进行了注释或元注释,Spring 将使用测试的 ApplicationContext 中对应的 bean 注入该特定参数的值。

If a parameter in a JUnit Jupiter test method or test lifecycle callback method is of type ApplicationContext (or a sub-type thereof) or is annotated or meta-annotated with @Autowired, @Qualifier, or @Value, Spring injects the value for that specific parameter with the corresponding bean from the test’s ApplicationContext.

在以下示例中,Spring 将从 TestConfig.class 加载的 ApplicationContext 中的 OrderService 注入到 deleteOrder() 测试方法:

In the following example, Spring injects the OrderService from the ApplicationContext loaded from TestConfig.class into the deleteOrder() test method:

  • Java

  • Kotlin

@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 中 ParameterResolver 支持的稳定性,您还可以将多个依赖项注入到一个方法中,不仅来自 Spring,还来自 JUnit Jupiter 本身或其他第三方扩展。

Due to the robustness of the ParameterResolver support in JUnit Jupiter, you can also have multiple dependencies injected into a single method, not only from Spring but also from JUnit Jupiter itself or other third-party extensions.

以下示例展示了如何让 Spring 和 JUnit Jupiter 同时为 placeOrderRepeatedly() 测试方法注入依赖项。

The following example shows how to have both Spring and JUnit Jupiter inject dependencies into the placeOrderRepeatedly() test method simultaneously.

  • Java

  • Kotlin

@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
	}
}

请注意,使用 JUnit Jupiter 中的 @RepeatedTest 会让测试方法能够访问 RepetitionInfo

Note that the use of @RepeatedTest from JUnit Jupiter lets the test method gain access to the RepetitionInfo.

@Nested test class configuration

Spring 测试上下文框架 从 Spring Framework 5.0 开始,支持在 JUnit Jupiter 的 @Nested 测试类上使用与测试相关的注解;然而,直到 Spring Framework 5.3,类级别的测试配置注解才不会像从超类继承的那样,从封闭类中`继承`。

The Spring TestContext Framework has supported the use of test-related annotations on @Nested test classes in JUnit Jupiter since Spring Framework 5.0; however, until Spring Framework 5.3 class-level test configuration annotations were not inherited from enclosing classes like they are from superclasses.

Spring Framework 5.3 引入了从封闭类中继承测试类配置的一流支持,并且此类配置将被默认继承。要从默认的 INHERIT 模式更改为 OVERRIDE 模式,可以使用 @NestedTestConfiguration(EnclosingConfiguration.OVERRIDE) 为单独的 @Nested 测试类添加注解。明确的 @NestedTestConfiguration 声明将应用于带有注解的测试类以及它的任何子类和嵌套类。因此,可以用 @NestedTestConfiguration 为顶级测试类添加注解,并且会在嵌套它的所有测试类中递归地应用它。

Spring Framework 5.3 introduced first-class support for inheriting test class configuration from enclosing classes, and such configuration will be inherited by default. To change from the default INHERIT mode to OVERRIDE mode, you may annotate an individual @Nested test class with @NestedTestConfiguration(EnclosingConfiguration.OVERRIDE). An explicit @NestedTestConfiguration declaration will apply to the annotated test class as well as any of its subclasses and nested classes. Thus, you may annotate a top-level test class with @NestedTestConfiguration, and that will apply to all of its nested test classes recursively.

为了允许开发团队更改为`OVERRIDE`的默认值——例如,为了与Spring Framework 5.0到5.2兼容——可以通过JVM系统属性或类路径根目录中的`spring.properties`文件在全局范围内更改默认模式。请参阅"Changing the default enclosing configuration inheritance mode"说明以了解详情。

In order to allow development teams to change the default to OVERRIDE – for example, for compatibility with Spring Framework 5.0 through 5.2 – the default mode can be changed globally via a JVM system property or a spring.properties file in the root of the classpath. See the "Changing the default enclosing configuration inheritance mode" note for details.

尽管以下“Hello World”示例非常简单,但它展示了如何在顶级类上声明公共配置,该类由其`@Nested`测试类继承。在此特定示例中,仅继承了`TestConfig`配置类。每个嵌套测试类都提供其自己的一组活动配置文件,从而为每个嵌套测试类生成了一个不同的`ApplicationContext`(请参阅Context Caching以了解详情)。查阅supported annotations列表以查看可以在`@Nested`测试类中继承哪些注解。

Although the following "Hello World" example is very simplistic, it shows how to declare common configuration on a top-level class that is inherited by its @Nested test classes. In this particular example, only the TestConfig configuration class is inherited. Each nested test class provides its own set of active profiles, resulting in a distinct ApplicationContext for each nested test class (see Context Caching for details). Consult the list of supported annotations to see which annotations can be inherited in @Nested test classes.

  • Java

  • Kotlin

@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")
		}
	}
}

TestNG Support Classes

org.springframework.test.context.testng 包为基于 TestNG 的测试用例提供了以下支持类:

The org.springframework.test.context.testng package provides the following support classes for TestNG based test cases:

  • AbstractTestNGSpringContextTests

  • AbstractTransactionalTestNGSpringContextTests

AbstractTestNGSpringContextTests 是一个抽象基础测试类,它在 TestNG 环境中集成了 Spring 测试上下文框架和显式的 ApplicationContext 测试支持。当扩展 AbstractTestNGSpringContextTests 时,可以访问 protected applicationContext 实例变量,可以用它执行显式 bean 查询或测试整个上下文的 state。

AbstractTestNGSpringContextTests is an abstract base test class that integrates the Spring TestContext Framework with explicit ApplicationContext testing support in a TestNG environment. When you extend AbstractTestNGSpringContextTests, you can access a protected applicationContext instance variable that you can use to perform explicit bean lookups or to test the state of the context as a whole.

`AbstractTransactionalTestNGSpringContextTests`是`AbstractTestNGSpringContextTests`的抽象事务扩展,为JDBC访问添加了一些便捷功能。此类期望在`ApplicationContext`中定义`javax.sql.DataSource`bean和`PlatformTransactionManager`bean。在扩展`AbstractTransactionalTestNGSpringContextTests`时,你可以访问`protected``jdbcTemplate`实例变量,可使用它来运行查询数据库的SQL语句。你可以使用此类查询来确认在运行与数据库相关的应用程序代码之前和之后的状态,并且Spring会确保此类查询在与应用程序代码相同的事务范围内运行。在与ORM工具结合使用时,请务必避免使用false positives。如JDBC Testing Support中所述,`AbstractTransactionalTestNGSpringContextTests`还提供了一些便利方法,通过使用上述`jdbcTemplate`来委托给`JdbcTestUtils`中的方法。此外,`AbstractTransactionalTestNGSpringContextTests`提供了一个`executeSqlScript(..)`方法,用于针对配置的`DataSource`运行SQL脚本。

AbstractTransactionalTestNGSpringContextTests is an abstract transactional extension of AbstractTestNGSpringContextTests that adds some convenience functionality for JDBC access. This class expects a javax.sql.DataSource bean and a PlatformTransactionManager bean to be defined in the ApplicationContext. When you extend AbstractTransactionalTestNGSpringContextTests, you can access a protected jdbcTemplate instance variable that you can use to run SQL statements to query the database. You can use such queries to confirm database state both before and after running database-related application code, and Spring ensures that such queries run in the scope of the same transaction as the application code. When used in conjunction with an ORM tool, be sure to avoid false positives. As mentioned in JDBC Testing Support, AbstractTransactionalTestNGSpringContextTests also provides convenience methods that delegate to methods in JdbcTestUtils by using the aforementioned jdbcTemplate. Furthermore, AbstractTransactionalTestNGSpringContextTests provides an executeSqlScript(..) method for running SQL scripts against the configured DataSource.

这些类便于扩展。如果您不希望您的测试类绑定到 Spring 特有的类层次结构,则可以使用 @ContextConfiguration@TestExecutionListeners 等手动为测试类添加 TestContextManager 插值,以配置您自己的自定义测试类。请参见 AbstractTestNGSpringContextTests 的源代码,了解如何为测试类添加插值示例。

These classes are a convenience for extension. If you do not want your test classes to be tied to a Spring-specific class hierarchy, you can configure your own custom test classes by using @ContextConfiguration, @TestExecutionListeners, and so on and by manually instrumenting your test class with a TestContextManager. See the source code of AbstractTestNGSpringContextTests for an example of how to instrument your test class.