之前用了不少Jmockit寫用例,多數還好,但是之前出現了一些問題,主要的問題是一些用例,使用eclipse運行是ok的,但是用mvn命令進行測試卻無法通過,錯誤的大致信息如下:
mockit.internal.expectations.invocation.MissingInvocation:
Missing 1 invocation to:
com.xxx.RegionService#getByRegionId(0)
on mock instance: com.xxx.RegionService.$Impl_RegionService@45430a27
at com.xxx.core.xxx.SomeTest.testXXX(SomeTest.java:38)
是一個MissingInvocation,意思很簡單,就是本來應該有一次調用,但實際上沒有執行。信息不難理解,麻煩的是2種環境的測試結果不一致。方法的聲明是這樣的:
Region getByRegionId(Integer regionId);
我的測試代碼時這樣寫的:
new Expectations(){
{
regionService.getByRegionId(3);
times = 1;
result = new RegionDTO(3,"縣名稱");
}
};
場景是這樣的:regionService是個外部的dubbo服務,CUT裏面,我需要根據地區的ID獲取地區名稱,會調用regionService.getByRegionId。 我在測試的時候使用Expectations來mock了getByRegionId的返回值。很簡單的測試,但是測試結果在mvn命令行運行的時候始終無法執行通過。網上搜索了半天沒什麼結果。在之前我都用Mockito的mock對象代替了Jmockit這種打樁方式,可以通過,但畢竟是權宜之計,沒搞清原因以後不知道要吃多大虧。
今天不是太忙,所以花時間解決了這個問題。原因就是surefire插件參數設置影響的,我的surefire配置是:
<configuration>
<reuseForks>true</reuseForks>
<forkCount>1</forkCount>
<argLine>-Dfile.encoding=${resources.encoding}</argLine>
<systemPropertyVariables>
<!-- <jacoco-agent.destfile>target/jacoco.exec</jacoco-agent.destfile> -->
</systemPropertyVariables>
</configuration>
而且再執行中發現,代碼被測試了2次(後來發現是我多配置了一個execution),第一次的結果是通過的,第二次失敗了。這我是用notepad++打開surefire-report中的txt文件發現的,測試過程中文件被改了2次。前後2次差90s左右,這個時間差應該和測試代碼的數量有關。
偶然搜到了網上的一個帖子:https://stackoverflow.com/questions/3365628/junit-tests-pass-in-eclipse-but-fail-in-maven-surefire
按照帖子的思路,大概就是插件參數或者junit的問題。所以不斷調整參數進行測試。
開始,參數調整爲:reuseForks=false,forkCount=1,這個配置可以通過,但是由於不允許複用進程,速度太慢,原來3分多鐘的測試,這種配置下跑了18分鐘才完事。有一件事可以肯定,這個配置測試確實只運行了1次。
最後調整爲reuseForks=true,forkCount=8 ,不用非要8,大概不是1應該就沒問題吧。
還有問題只是使用Jmockit纔會有,用mockito是沒有問題的。
補充一下,測試2次的問題主要是除了默認的execution之外,我還配置一個run-execution,仔細看測試的輸出是可以看到1個同樣的測試類被default-execution和run-execution都執行了一次。