2016-05-16 92 views
0

根據以下鏈接:https://stackoverflow.com/a/20056622/1623597https://stackoverflow.com/a/15640575/1623597 TestNG不會在每個方法測試中創建新實例。強制TestNG爲每個方法測試創建新實例

我有spring引導應用程序。我需要編寫集成測試(Controller,service,Repositories)。有時候要創建新的測試用例,我需要在DB中使用一些實體。要忘記db中的任何預定義實體,我決定模擬庫層。我剛剛實現了ApplicationContextInitializer,它可以在類路徑中找到所有JPA Repository,並將它們添加到Spring上下文中。

我有一個新的問題,我的模擬創建一次每個ControllerTest(擴展AbstractTestNGSpringContextTests)。經過測試的上下文只創建一次,並且所有方法的模擬實例都是相同的。現在,我有

//All repos are mocked via implementation of ApplicationContextInitializer<GenericWebApplicationContext> 
// and added to spring context by 
//applicationContext.getBeanFactory().registerSingleton(beanName, mock(beanClass)); //beanClass in our case is StudentRepository.class 
@Autowired 
StudentRepository studentRepository; 

//real MyService implementation with autowired studentRepository mock 
@Autowired 
MyService mySevice; 

@Test 
public void test1() throws Exception { 
    mySevice.execute();  //it internally calls studentRepository.findOne(..); only one time 
    verify(studentRepository).findOne(notNull(String.class)); 
} 

//I want that studentRepository that autowired to mySevice was recreated(reset) 
@Test 
public void test2() throws Exception { 
    mySevice.execute();  //it internally calls studentRepository.findOne(..); only one time 
    verify(studentRepository, times(2)).findOne(notNull(String.class)); //I don't want to use times(2) 
    //times(2) because studentRepository has already been invoked in test1() method 

} 

@Test 
public void test3() throws Exception { 
    mySevice.execute();  //it internally calls studentRepository.findOne(..); only one time 
    verify(studentRepository, times(3)).findOne(notNull(String.class)); //I don't want to use times(3) 
} 

我需要增加每一個後續method.I次(N)瞭解到,這是TestNG的實現,但我試圖找到很好的解決方案給我。對於我的服務,我使用構造函數自動裝配,所有字段都是最終的。

問題:

  1. 是否有可能迫使TestNG的爲每個測試方法創建新實例? 我可以爲每個方法測試重新創建彈簧上下文嗎?

  2. 我可以爲每個模擬存儲庫創建自定義代理並通過代理在@BeforeMethod方法中重置模擬嗎?

+0

你已經嘗試重置你想要在@/AfterMethod之前? – juherr

+0

我不能使用這種方法。原因是我可以有10個存儲庫,在另外20個服務中使用。每一項服務都使用構造函數自動裝配並且具有最終字段。此外,我無法在@ Before/AfterMethod中覆蓋所有服務並替換mocks – Geniy

+0

如何初始化myService? – juherr

回答

0

其實我不需要在上下文中創建新的存儲庫模擬實例,我只需要重置它們的狀態。 我認爲Mockito.reset(模擬)只是創建新的實例,並將其分配給參考模擬到目前爲止。 但事實並非如此。 Mockito.reset的真實行爲只是清理當前的模擬狀態而不創建新的模擬實例。

我的解決辦法:

import org.springframework.data.repository.Repository; 

@Autowired 
private List<Repository> mockedRepositories; 

@BeforeMethod 
public void before() { 
    mockedRepositories.forEach(Mockito::reset); 
} 

此代碼自動裝配在ApplicationContextInitializer被嘲笑,所有的回購協議,並重置它們的狀態。 現在,我可以使用驗證()沒有時間(2)

@Test 
public void test2() throws Exception { 
    mySevice.execute() 
    verify(studentRepository).findOne(notNull(String.class)); 
} 
相關問題