[英]Usages of doThrow() doAnswer() doNothing() and doReturn() in mockito
[英]Mockito, Usages of doNothing() When()
我是 Mockito 的新手,我回顧了這個例子,但是當它在方法的第一行調用doNothing()
時,有一個步驟我不明白:
@Test(expected = RuntimeException.class)
public void testConsecutiveCalls() throws Exception(){
doNothing().doThrow(Exception.class).when(b).voidMethod();
a.usesVoidMethod()
verify(b).voidMethod();
a.usesVoidMethod()
}
我確實明白,當第一次voidMehtod()
時沒有返回任何內容,而第二次則給出異常。
但是如果我們刪除doNothing.doThrow(Exception.class).when(b).voidMethod();
,測試是否仍然有效並且會測試我們想要測試的方法是否在第二次拋出異常?
有幾點,編號只是為了方便參考:
模擬的默認行為是每次都返回一個適當的虛擬值,通常是零、 null
或空字符串。 間諜的默認行為是調用間諜的真實實現。 當然,通過@Mock
或Mockito.mock
的參數,您可以使用任意答案或任何 Mockito 的標准或附加答案。
當多個動作作為鏈的一部分給出時,Mockito 將按順序執行每個動作並永遠重復最后一個動作。
// calls to foo.bar() return 1, 2, 3, 3, 3... doReturn(1).thenReturn(2, 3).when(foo).bar();
請注意,這是在同一個鏈中; 最近定義的匹配鏈獲勝,因此單獨的語句不會產生相同的效果。
doReturn(1).thenReturn(2).when(foo).baz(); doReturn(3).thenReturn(4).when(foo).baz(); // calls return 3, 4, 4, 4... because the first chain is entirely overridden.
然后, doNothing
的大部分價值來自覆蓋默認行為或在鏈中設置操作。
所以測試試圖做的是第一次做任何事情以使驗證成功,然后第二次doThrow
doNothing
滿足預期的異常。 盡管失敗的verify
會(正確地)使測試失敗,因為Mockito 的錯誤子類 Error 而不是 Exception ,但你是對的,刪除doNothing
仍然會通過在第一次調用a.usesVoidMethod()
. 雖然這對於測試來說已經足夠好了——畢竟,你可以在測試本身中看到doNothing
一個更健壯的測試可能看起來像這樣:
@Test
public void testConsecutiveCalls() throws Exception(){
doNothing().doThrow(SomeKnownException.class).when(b).voidMethod();
a.usesVoidMethod();
verify(b).voidMethod();
try {
a.usesVoidMethod();
fail();
} catch (SomeKnownException expected) { /* OK */ }
}
doNothing
方法不會改變模擬方法的行為mocked' method, but the declaration of the
改變does. If you have a spy and don't want a method to be executed, then
does. If you have a spy and don't want a method to be executed, then
doNothing` 將改變行為。
這個測試是一個糟糕的測試,因為 (a) 它沒有多大意義,(b) 它正在測試兩個不同的東西:
a.usesVoidMethod()
調用b.voidMethod()
。b
拋出Exception
時,被測對象a
拋出RuntimeException
。和 (c),它的名稱不正確。 它正在獨立測試上面的兩件事,它們是連續調用的事實是無關緊要的。
如果您刪除此測試方法的第一行,那么您將刪除正在模擬的b
的行為。 然后測試將失敗,因為默認情況下對模擬的 void 方法調用不會執行任何操作; 即,不會有來自b
的Exception
,因此不會有來自a
RuntimeException
。
你是對的,如果a
被實際編碼,如果它被調用兩次,它會拋出一個RuntimeException
,那么就不需要模擬b
。 但這將比現在更不合理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.