持續集成之路 —— Mock對象引起的測試失敗

        今天遇到了一個很奇怪的問題,糾結了好久。在和同事唸叨這個問題時,突然想到了問題所在。

        問題現象: 在一個Service的單元測試類中有八個測試用例,單獨運行時都可以正常通過。可是一旦一起運行時,總是會有固定的兩個測試失敗。

        問題原因:有一個測試用例mock了Service依賴的一個Dao對象,之後的用例再使用這個Dao對象時,就使用了mock,而不是Spring初始化的Instance.

        解決方法:在測試用例結束,重新將Spring初始化Dao對象set給Service對象,具體代碼:

public class ReportServiceTest {
    //被測試的Service,由Spring初始化
    @Autowired
    private UserService userService;
    //Service依賴的Dao,由Spring初始化
    @Autowired
    private UserDao userDao;

    @Test
    @DatabaseSetup("dataset.xml") //測試數據集
    public void testGetManager(){
        //創建mock對象
        UserDao mockUserDao = mock(UserDao.class);
	//設置mock的Dao要模擬的操作
        when(...).thenReturn(..);
        //替換依賴
        ((UserServiceImpl)userService).setUserDao(mockUserDao);
        
        //具體測試代碼
        ……
        
	//將mock的dao替換掉
        ((UserServiceImpl)userService).setUserDao(userDao);
    }
}


       除了上面的方法,還可以通過設定用例的執行順序解決上面的問題。但是這個方法還是具有一定的危險性,一定要保證使用mock對象的測試用例最後執行,並且所有使用mock對象的用例之間要安排好執行順序。關於如何指定測試用例的執行順序,可以參考下面的文章:

Understanding JUnit method order execution
JUnit test method ordering
Ordered testcases execution in junit 4



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章