此版本仍在开发中,尚不被认为是稳定的。对于最新的稳定版本,请使用 Spring Framework 6.2.10spring-doc.cadn.net.cn

测试夹具的依赖注入

当您使用DependencyInjectionTestExecutionListener(由 默认),测试实例的依赖项是从 配置时使用的应用程序上下文@ContextConfiguration或相关 附注。您可以使用 setter 注入、字段注入或两者兼而有之,具体取决于 您选择哪些注释,以及是否将它们放在 setter 方法或字段上。 如果您使用的是 JUnit Jupiter,您还可以选择使用构造函数注入 (参见依赖注入SpringExtension). 为了与 Spring 基于注释的注入支持保持一致,您还可以使用 Spring的@Autowired注释或@InjectJSR-330 的注释 田和二雏器注入。spring-doc.cadn.net.cn

对于 JUnit Jupiter 以外的测试框架,TestContext 框架不会 参与测试类的实例化。因此,使用@Autowired@Injectfor 构造函数对测试类没有影响。
尽管在生产代码中不鼓励字段注入,但字段注入是 实际上在测试代码中很自然。差异的基本原理是,您将 切勿直接实例化测试类。因此,没有必要能够 调用public构造函数或 setter 方法。

因为@Autowired用于按类型执行自动装配,如果您有多个相同类型的 bean 定义,则不能依赖此 方法。在这种情况下,您可以使用@Autowired在 结合@Qualifier.您也可以选择使用@Inject结合@Named.或者,如果您的测试类可以访问其ApplicationContext你 可以通过使用(例如)调用applicationContext.getBean("titleRepository", TitleRepository.class).spring-doc.cadn.net.cn

如果您不希望将依赖项注入应用于测试实例,请不要注释 fields 或 setter 方法与@Autowired@Inject.或者,您可以禁用 通过显式配置您的类来完全注入依赖项@TestExecutionListeners并省略DependencyInjectionTestExecutionListener.class从监听器列表中。spring-doc.cadn.net.cn

考虑测试HibernateTitleRepository类,如目标部分所述。接下来的两个代码 列表展示了@Autowiredon 字段和 setter 方法。应用 上下文配置显示在所有示例代码列表之后。spring-doc.cadn.net.cn

以下代码列表中的依赖注入行为并非特定于 JUnit 木星。相同的 DI 技术可以与任何受支持的测试结合使用 框架。spring-doc.cadn.net.cn

以下示例调用静态断言方法,例如assertNotNull(), 但不在调用前加上Assertions.在这种情况下,假设方法 通过import static声明中未显示的 例。spring-doc.cadn.net.cn

第一个代码列表显示了基于 JUnit Jupiter 的测试类实现,该测试类 使用@Autowired用于现场注射:spring-doc.cadn.net.cn

@ExtendWith(SpringExtension.class)
// specifies the Spring configuration to load for this test fixture
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {

	// this instance will be dependency injected by type
	@Autowired
	HibernateTitleRepository titleRepository;

	@Test
	void findById() {
		Title title = titleRepository.findById(new Long(10));
		assertNotNull(title);
	}
}
@ExtendWith(SpringExtension::class)
// specifies the Spring configuration to load for this test fixture
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {

	// this instance will be dependency injected by type
	@Autowired
	lateinit var titleRepository: HibernateTitleRepository

	@Test
	fun findById() {
		val title = titleRepository.findById(10)
		assertNotNull(title)
	}
}

或者,您可以将类配置为使用@Autowired对于入孵机注射,如 遵循:spring-doc.cadn.net.cn

@ExtendWith(SpringExtension.class)
// specifies the Spring configuration to load for this test fixture
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {

	// this instance will be dependency injected by type
	HibernateTitleRepository titleRepository;

	@Autowired
	void setTitleRepository(HibernateTitleRepository titleRepository) {
		this.titleRepository = titleRepository;
	}

	@Test
	void findById() {
		Title title = titleRepository.findById(new Long(10));
		assertNotNull(title);
	}
}
@ExtendWith(SpringExtension::class)
// specifies the Spring configuration to load for this test fixture
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {

	// this instance will be dependency injected by type
	lateinit var titleRepository: HibernateTitleRepository

	@Autowired
	fun setTitleRepository(titleRepository: HibernateTitleRepository) {
		this.titleRepository = titleRepository
	}

	@Test
	fun findById() {
		val title = titleRepository.findById(10)
		assertNotNull(title)
	}
}

前面的代码列表使用与@ContextConfiguration注释(即,repository-config.xml).以下内容 显示此配置:spring-doc.cadn.net.cn

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		https://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- this bean will be injected into the HibernateTitleRepositoryTests class -->
	<bean id="titleRepository" class="com.foo.repository.hibernate.HibernateTitleRepository">
		<property name="sessionFactory" ref="sessionFactory"/>
	</bean>

	<bean id="sessionFactory" class="org.springframework.orm.jpa.hibernate.LocalSessionFactoryBean">
		<!-- configuration elided for brevity -->
	</bean>

</beans>

如果您从 Spring 提供的测试基类扩展,该基类恰好使用@Autowired在其 setter 方法之一上,您可能有多个受影响的 bean 类型(例如,多个DataSource豆子)。在 在这种情况下,您可以覆盖 setter 方法并使用@Qualifier注释到 指示特定的目标 bean,如下所示(但请确保委托给被覆盖的 方法也一样):spring-doc.cadn.net.cn

// ...

	@Autowired
	@Override
	public void setDataSource(@Qualifier("myDataSource") DataSource dataSource) {
		super.setDataSource(dataSource);
	}

// ...
// ...

	@Autowired
	override fun setDataSource(@Qualifier("myDataSource") dataSource: DataSource) {
		super.setDataSource(dataSource)
	}

// ...

指定的限定符值表示特定的DataSource要注入的豆子, 将类型匹配集缩小到特定 bean。其值与<qualifier>相应的声明<bean>定义。bean 名称 用作回退限定符值,因此您还可以有效地指向特定的 bean 的名称(如前所示,假设myDataSource是豆子id).spring-doc.cadn.net.cn