使用TestExecutionListener时,Spring测试注入不起作用

我想将自定义的TestExecutionListenerSpringJUnit4ClassRunner结合使用,在我的测试数据库上运行Liquibase架构设置。 我的TestExecutionListener工作正常但是当我在我的类上使用注释时,测试中的DAO注入不再起作用,至少实例为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 devices = deviceDAO.findByCategory(1); // deviceDAO null -> NPE ... } } 

听众很简单:

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

日志中没有错误,只是我的测试中出现NullPointerException 。 我没有看到我的TestExecutionListener的使用如何影响自动assembly或注入。

我看了一下spring DEBUG日志,发现当我省略自己的TestExecutionListener时,Spring会设置一个DependencyInjectionTestExecutionListener。 使用@TestExecutionListeners注释测试时,侦听器会被覆盖。

所以我刚刚使用我的自定义添加了DependencyInjectionTestExecutionListener,一切正常:

 @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 { ... 

更新: 此处记录了此行为。

…或者,您可以通过使用@TestExecutionListeners显式配置类并从侦听器列表中省略DependencyInjectionTestExecutionListener.class来完全禁用依赖项注入。

我建议考虑做以下事情:

 @TestExecutionListeners( mergeMode =TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS, listeners = {MySuperfancyListener.class} ) 

这样您就不需要知道需要哪些监听器。 我推荐这种方法是因为SpringBoot在几分钟内努力尝试通过使用DependencyInjectionTestExecutionListener.class使其正常工作。