2013-03-29 40 views
13

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

@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影响自动装配或注入。

回答

20

我看了一下Spring的DEBUG日志,发现当我省略自己的TestExecutionListener时,弹簧设置了一个DependencyInjectionTestExecutionListener。用@TestExecutionListeners注释测试者被覆盖时注释测试。

所以我只是用我自定义的添加DependencyInjectionTestExecutionListener明确,一切工作正常:

​​

UPDATE: 的行为记录在案here

...或者,您也可以完全用@TestExecutionListeners明确配置类和听众的清单中移除的DependencyInjectionTestExecutionListener.class禁用依赖注入。

+1

这是正确的:如果你通过'@ TestExecutionListeners'指定了一个自定义的'TestExecutionListener',你隐式地覆盖了所有的默认TestExecutionListeners。当然,这个功能可能没有那么好记录。因此,请随时打开JIRA问题以请求对文档进行改进。 ;) –

+1

@SamBrannen:实际上它被记录 - 也许有些含蓄。看到我更新的答案。 – nansen

+2

我非常了解自你写作以来引用的文字。 ;)但是...没有明确描述你遇到的情况。这就是为什么我建议你打开JIRA票证来改进文档。 –

3

我会建议考虑只是做这样的事情:

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

,这样你就不需要知道需要哪些听众。我推荐这种方法,因为SpringBoot试图通过使用DependencyInjectionTestExecutionListener.class来努力工作几分钟。