|
对于最新的稳定版本,请使用 Spring Framework 7.0.6! |
测试夹具的依赖注入
当你使用 DependencyInjectionTestExecutionListener(默认配置为DependencyInjectionTestExecutionListener),你的测试实例的依赖项将从你在@ContextConfiguration或相关注解中配置的应用上下文中注入。你可以使用属性注入、字段注入,或者两者都使用,这取决于你选择的注解以及你是否将它们放在setter方法或字段上。如果你正在使用JUnit Jupiter,你还可以选择性地使用构造器注入(参见使用SpringExtension进行依赖注入)。为了与Spring的注解式注入支持保持一致,你也可以使用Spring的@Autowired注解或JSR-330的@Inject注解来进行字段和setter注入。
For testing frameworks other than JUnit Jupiter, the TestContext framework does not
participate in instantiation of the test class. Thus, the use of @Autowired or
@Inject for constructors has no effect for test classes. |
| 虽然字段注入在生产代码中不被推荐,但在测试代码中字段注入实际上是相当自然的。这种差异的原因是你永远不会直接实例化你的测试类。因此,没有必要能够在你的测试类上调用无参构造函数或setter方法。 |
因为@Autowired用于按类型自动装配,如果你有多个相同类型的bean定义,你不能依赖这种方法。在这种情况下,你可以使用@Autowired与@Qualifier一起。你也可以选择使用@Inject与@Named一起。或者,如果你的测试类可以访问其ApplicationContext,你可以通过显式查找来执行此操作,例如调用applicationContext.getBean("titleRepository", TitleRepository.class)。
如果您不希望将依赖注入应用于测试实例,请不要使用 @Autowired 或 @Inject 注解字段或setter方法。或者,您可以通过显式配置您的类为 @TestExecutionListeners 并从监听器列表中省略 DependencyInjectionTestExecutionListener.class 来完全禁用依赖注入。
考虑测试 HibernateTitleRepository 类的情景,如在目标部分所述。接下来的两个代码示例展示了在字段和setter方法中使用 @Autowired 的情况。所有示例代码列出后将展示应用程序上下文配置。
|
以下代码示例中的依赖注入行为并不特定于JUnit Jupiter。相同的DI技术可以与任何受支持的测试框架结合使用。 以下示例调用了静态断言方法,例如 |
第一个代码示例展示了一个基于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)
}
}
或者,您可以配置该类使用 @Autowired 进行setter注入,如下所示:
-
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)
}
}
上述代码示例使用了由@ContextConfiguration注解引用的同一个XML上下文文件(即,repository-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方法中使用了
指定的限定符值指示要注入的具体 |