[英]Mockito, verify a function is invoked 0 time(s)
我正在使用Mockito來編寫我的測試用例。 我有一個簡單的類,其中包含一個函數countPerson(boolean)
,我有興趣測試它:
public class School {
//School is a singleton class.
public void countPerson(boolean includeTeacher) {
if (includeTeacher) {
countIncludeTeacher();
return;
}
countOnlyStudents();
}
public void countIncludeTeacher() {...}
public void countOnlyStudents() {...}
}
在我的單元測試中,我想測試countPerson(boolean)
方法:
@Test
public void testCountPerson() {
School mSchool = School.getInstance();
School spySchool = Mockito.spy(mSchool);
spySchool.countPerson(true);
//Verify the function countIncludeTeacher is invoked once
verify(spySchool).countIncludeTeacher();
//Until here things are working well.
spySchool.countPerson(false);
//ERROR HERE when I try to verify the function has 0 times invoke
verify(spySchool, times(0)).countIncludeTeacher();
}
我有以下錯誤:
org.mockito.exceptions.verification.NeverWantedButInvoked:school.countIncludeTeacher(); 從未想過這里:(SchoolTest.java 20)
為什么0次驗證不起作用?
實際上,問題是每個verify
調用都是在同一個spySchool
實例上進行的。 讓我解釋:
@Test
public void testCountPerson() {
School mSchool = School.getInstance();
School spySchool = Mockito.spy(mSchool); // a spy is created here, Mockito is listening in.
spySchool.countPerson(true); // real method is invoked
verify(spySchool).countIncludeTeacher(); // our spy identified that countIncludeTeacher was called
spySchool.countPerson(false); // real method is invoked
verify(spySchool, times(0)).countIncludeTeacher(); // our spy still identified that countIncludeTeacher was called, before it was called before
}
問題是,在最新的verify
,它失敗了,因為之前在間諜上調用了countIncludeTeacher
方法,並且該調用未被注銷。
您可以使用verifyNoMoreInteractions
執行此操作,該驗證驗證對象沒有更多交互。 您也可以重置該對象。
但請注意,這不是真的不推薦,引用Mockito Javadoc:
警告 :有些用戶經常做很多經典的,期望運行驗證的
verifyNoMoreInteractions()
往往會經常使用verifyNoMoreInteractions()
,即使在每種測試方法中也是如此。 建議不要在每個測試方法中使用verifyNoMoreInteractions()
。verifyNoMoreInteractions()
是交互測試工具包中的一個方便的斷言。 僅在相關時使用它。 濫用它會導致過度指定,不易維護的測試。 你可以在這里找到進一步閱讀。
和
Smart Mockito用戶幾乎不使用此功能,因為他們知道這可能是測試不佳的標志。 通常,您不需要重置模擬,只需為每個測試方法創建新的模擬。
請考慮在冗長,過度指定的測試中編寫簡單,小巧且集中的測試方法,而不是
reset()
。 在測試方法的中間,第一個潛在的代碼氣味被reset()
。 這可能意味着你的測試太多了。 按照你的測試方法的低語:“請保持我們小,專注於單一行為”。
我肯定建議你將這個測試分成兩部分:一部分用於true
案例,一部分用於false
案例。
它失敗是因為您在測試中運行spySchool.countPerson(true)
時實際上會調用countIncludeTeacher()
。 這將分支到您的其他函數,重新編碼為間諜對象上的調用。
在當前的設置中,您要么必須驗證它只被調用一次,要么在運行第二次測試之前重置間諜對象實例。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.