java - 使用 TestExecutionListener 时 Spring 测试注入(inject)不起作用

标签 java spring liquibase spring-test

我想结合使用自定义 TestExecutionListenerSpringJUnit4ClassRunner 在我的测试数据库上运行 Liquibase 模式设置。我的 TestExecutionListener 工作正常,但是当我在我的类上使用注释时,被测 DAO 的注入(inject)不再起作用,至少实例为空。

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

监听器相当简单:

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 的使用如何影响 Autowiring 或注入(inject)。

最佳答案

我查看了 spring 调试日志,发现当我省略自己的 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 {
    ...

更新: 该行为记录在here .

... Alternatively, you can disable dependency injection altogether by explicitly configuring your class with @TestExecutionListeners and omitting DependencyInjectionTestExecutionListener.class from the list of listeners.

关于java - 使用 TestExecutionListener 时 Spring 测试注入(inject)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15704091/

相关文章:

java - 如何根据文件中的数据类型将 CSV 文件读入 2 个 ArrayList?

java - 自动将 Clojure 源代码转换为 Java 源代码的最佳方法

java - 创建随 secret 码会生成长度为 0 : Blame JavaScript or Java Servlet? 的密码

java - 在 Aspose-Cells 的一个单元格中应用多种样式

java - 如何将 url 中的查询字符串传递的值传递到 spring Controller 中?

java - Maven 关闭默认目标执行

java - Postgresql 的 Liquibase addAutoIncrement 错误

java - 在类路径资源 [spring/database/DataSource.xml] 中定义了名称为 'dataSource' 的无效 bean 定义

java - Spring Data REST,如何处理列表中的@Version 属性

cassandra - 如何使用 scyllaDB 实现 Liquibase?