2013-03-29 42 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來努力工作幾分鐘。