当您使用 (由 default),测试实例的依赖项是从 bean 中注入的 配置或相关的应用程序上下文 附注。您可以使用二传手注射、现场注射或两者兼而有之,具体取决于 选择哪些注释,以及是否将它们放在 setter 方法或字段上。 如果您使用的是 JUnit Jupiter,您还可以选择使用构造函数注入 (请参阅使用 SpringExtension 进行依赖注入)。为了与 Spring 的基于注解的一致性 注入支持,您也可以使用 Spring 的注释或 JSR-330 的注释进行现场和二传手注入。DependencyInjectionTestExecutionListener@ContextConfiguration@Autowired@Inject

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

因为 用于按类型执行自动接线 ,如果您有多个相同类型的 Bean 定义,则不能依赖此定义 这些特定豆类的方法。在这种情况下,您可以在 结合。您也可以选择与 结合使用。或者,如果您的测试类有权访问其 ,则 可以通过使用(例如)对 的调用来执行显式查找。@Autowired@Autowired@Qualifier@Inject@NamedApplicationContextapplicationContext.getBean("titleRepository", TitleRepository.class)

如果您不希望将依赖项注入应用于测试实例,请不要注释 字段或 setter 方法与 或 .或者,您可以禁用 完全通过显式配置类来完全注入依赖关系,并从侦听器列表中省略。@Autowired@Inject@TestExecutionListenersDependencyInjectionTestExecutionListener.class

考虑测试类的场景,如“目标”部分所述。接下来的两个代码清单演示了 使用 on 字段和 setter 方法。应用程序上下文配置 显示在所有示例代码列表之后。HibernateTitleRepository@Autowired

以下代码清单中的依赖项注入行为并非特定于 JUnit 木星。相同的 DI 技术可以与任何支持的测试结合使用 框架。

以下示例调用静态断言方法,例如 , 但不以 .在这种情况下,假设该方法 已通过未显示在 例。assertNotNull()Assertionsimport static

第一个代码列表显示了测试类的基于 JUnit Jupiter 的实现,该类 现场注射的用途:@Autowired

  • Java

  • Kotlin

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

或者,您可以配置用于 setter 注入的类,如 遵循:@Autowired

  • Java

  • Kotlin

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

前面的代码清单使用注释引用的相同 XML 上下文文件(即 )。以下 显示以下配置:@ContextConfigurationrepository-config.xml

<?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.hibernate5.LocalSessionFactoryBean">
		<!-- configuration elided for brevity -->
	</bean>

</beans>

如果要从 Spring 提供的测试基类扩展,而该基类恰好在其某个 setter 方法上使用,则可能有多个受影响的 bean 在应用程序上下文中定义的类型(例如,多个 Bean)。在 在这种情况下,您可以重写 setter 方法并使用注释来 指示特定的目标 Bean,如下所示(但请确保委托给 Overrided 方法):@AutowiredDataSource@Qualifier

  • Java

  • Kotlin

// ...

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

// ...
// ...

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

// ...

指定的限定符值指示要注入的特定 Bean, 将类型匹配的集合缩小到特定 Bean。其值与相应定义中的声明匹配。Bean 名称 用作回退限定符值,因此您也可以有效地指向特定的 bean 按名称命名(如前所述,假设是 bean )。DataSource<qualifier><bean>myDataSourceid