Spring test injection not working when using TestExecutionListener
java, liquibase, spring, spring-test
Solution
I had a look at the spring DEBUG logs and found that when I omit my own TestExecutionListener spring sets a DependencyInjectionTestExecutionListener in place. When annotating the test with @TestExecutionListeners that listener gets overwritten.
So I just added the DependencyInjectionTestExecutionListener explicitly with my custom one and everything works fine:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/applicationContext-test.xml" })
@TestExecutionListeners(listeners = { LiquibaseTestExecutionListener.class,
DependencyInjectionTestExecutionListener.class })
@LiquibaseChangeSet(changeSetLocations = { "liquibase/v001/createTables.xml" })
public class DeviceDAOTest {
...
UPDATE: The behavior is documented here.
... Alternatively, you can disable dependency injection altogether by explicitly configuring your class with @TestExecutionListeners and omitting DependencyInjectionTestExecutionListener.class from the list of listeners.
Problem
I want to use a custom `TestExecutionListener` in combination with `SpringJUnit4ClassRunner` to run a Liquibase schema setup on my test database. My `TestExecutionListener` works fine but when I use the annotation on my class the injection of the DAO under test no longer works, at least the instance is null. ``` @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/applicationContext-test.xml" }) @TestExecutionListeners({ LiquibaseTestExecutionListener.class }) @LiquibaseChangeSet(changeSetLocations={"liquibase/v001/createTables.xml"}) public class DeviceDAOTest { ... @Inject DeviceDAO deviceDAO; @Test public void findByCategory_categoryHasSubCategories_returnsAllDescendantsDevices() { List<Device> devices = deviceDAO.findByCategory(1); // deviceDAO null -> NPE ... } } ``` The listener is fairly simple: ``` public class LiquibaseTestExecutionListener extends AbstractTestExecutionListener { @Override public void beforeTestClass(TestContext testContext) throws Exception { final LiquibaseChangeSet annotation = AnnotationUtils.findAnnotation(testContext.getTestClass(), LiquibaseChangeSet.class); if (annotation != null) { executeChangesets(testContext, annotation.changeSetLocations()); } } private void executeChangesets(TestContext testContext, String[] changeSetLocation) throws SQLException, LiquibaseException { for (String location : changeSetLocation) { DataSource datasource = testContext.getApplicationContext().getBean(DataSource.class); DatabaseConnection database = new JdbcConnection(datasource.getConnection()); Liquibase liquibase = new Liquibase(location, new FileSystemResourceAccessor(), database); liquibase.update(null); } } } ``` There are no errors in the log, just a `NullPointerException` in my test. I don't see how the use of my `TestExecutionListener` affects the autowiring or injection.