If you use the DependencyInjectionTestExecutionListener (which is configured by default), your test instances' dependencies are injected from beans in the application context that you configured using the @ContextConfiguration annotation or related annotations . You can use setter dependency injection, field dependency injection, or both, depending on which annotations you choose and whether you place them in setters or fields. If you are using JUnit Jupiter, you can also optionally use constructor injection (see "Dependency Injection with SpringExtension"). For consistency with Spring's annotation-based dependency injection support, you can also use the @Autowired annotation or the @Inject annotation from JSR-330 to perform dependency injection via field and setter.

For test frameworks other than JUnit Jupiter, the TestContext framework is not involved in instantiating the test class. Therefore, using the @Autowired or @Inject annotation on constructors has no effect on test classes.
Although it is not recommended to use dependency injection through a field in code for deployment in a production environment, injecting dependencies through a field in test code is quite natural. The difference is that you will never have to instantiate your test class directly. Therefore, there is no need to call the public constructor or setter in your test class.

Because the @Autowired annotation is used to perform automatic detection and linking by typeif you have multiple bean definitions of the same type, you won't be able to use this approach for those specific beans. In this case, you can use the @Autowired annotation in combination with the @Qualifier annotation. You can also use the @Inject annotation in combination with the @Named annotation. Additionally, if your test class has access to its ApplicationContext, you can perform an explicit sequential lookup using (for example) calling applicationContext.getBean("titleRepository", TitleRepository.class).

If you need dependency injection to be applied to your test instances, do not annotate fields or setters with the @Autowired annotation or the @Inject annotation. Alternatively, you can disable dependency injection entirely by explicitly configuring your class to use the @TestExecutionListeners annotation and excluding DependencyInjectionTestExecutionListener.class from the list of listeners.

Consider the testing scenario for the HibernateTitleRepository class, as described in the section "Goals". The following two code listings demonstrate the use of the @Autowired annotation for fields and setters. The application context configuration is presented after all example code listings.

The dependency injection logic in the following code listings is not specific to JUnit Jupiter. The same dependency injection techniques can be used in combination with any supported testing framework.

The following examples call static methods with an assertion, such as assertNotNull(), but without first calling Assertions. In such cases, assume that the method was properly imported via an import static declaration, which is not shown in the example.

The first code listing shows an implementation of a JUnit Jupiter-based test class that uses the @Autowired annotation for dependency injection via a field:

Java
@ExtendWith(SpringExtension.class)
// defines the loaded Spring configuration for this testbench
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {
    // this instance will be injected with a dependency by type
    @Autowired
    HibernateTitleRepository titleRepository;
    @Test
    void findById() {
        Title title = titleRepository.findById(new Long(10));
        assertNotNull(title);
    }
}
Kotlin
@ExtendWith(SpringExtension::class)
// defines the loaded Spring configuration for this testbench
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {
    // this instance will be injected with a dependency by type
    @Autowired
    lateinit var titleRepository: HibernateTitleRepository
    @Test
    fun findById() {
        val title = titleRepository.findById(10)
        assertNotNull(title)
    }
}

Alternatively, you can configure the class to use the @Autowired annotation for dependency injection via a setter, as shown below:

Java
@ExtendWith(SpringExtension.class)
// defines the loaded Spring configuration for this testbench
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {
    // this instance will be injected with a dependency by type
    HibernateTitleRepository titleRepository;
    @Autowired
    void setTitleRepository(HibernateTitleRepository titleRepository) {
        this.titleRepository = titleRepository;
    }
    @Test
    void findById() {
        Title title = titleRepository.findById(new Long(10));
        assertNotNull(title);
    }
}
Kotlin
@ExtendWith(SpringExtension::class)
// defines the loaded Spring configuration for this testbench
@ContextConfiguration("repository-config.xml")
class HibernateTitleRepositoryTests {
    // this instance will be injected with a dependency by type
    lateinit var titleRepository: HibernateTitleRepository
    @Autowired
    fun setTitleRepository(titleRepository: HibernateTitleRepository) {
        this.titleRepository = titleRepository
    }
    @Test
    fun findById() {
        val title = titleRepository.findById(10)
        assertNotNull(title)
    }
}

The previous code listings use the same XML context file referenced by the @ContextConfiguration annotation (that is, repository-config.xml). This configuration is shown below:

<?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 omitted for the sake of brevity -->
    </bean>
</beans>

If you extend a main test class provided by Spring that uses the @Autowired annotation in one of its setters, you may have multiple beans of the corresponding type defined in your application context (for example, multiple beans DataSource ). In this case, you can override the setter and use the @Qualifier annotation to specify a specific target bean, as shown below (but be sure to also delegate to the overridden method in the superclass):

Java
// ...
    @Autowired
    @Override
    public void setDataSource(@Qualifier("myDataSource") DataSource dataSource) {
        super.setDataSource(dataSource);
    }
// ...
Kotlin
// ...
    @Autowired
    override fun setDataSource(@Qualifier("myDataSource") dataSource: DataSource) {
        super.setDataSource(dataSource)
    }
// ...

The specified qualifier value points to the specific DataSource bean to be injected, narrowing the set of type matches to the specific bean. Its value is matched against <qualifier> declarations in corresponding <bean> definitions. The bean name is used as the return value of the qualifier so that a specific bean can be properly referenced by name (as shown earlier, assuming myDataSource is the id of the bean).