簡體   English   中英

Mockito,doNothing() When() 的用法

[英]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(); ,測試是否仍然有效並且會測試我們想要測試的方法是否在第二次拋出異常?

有幾點,編號只是為了方便參考:

  1. 模擬的默認行為是每次都返回一個適當的虛擬值,通常是零、 null或空字符串。 間諜的默認行為是調用間諜的真實實現。 當然,通過@MockMockito.mock的參數,您可以使用任意答案或任何 Mockito 的標准附加答案。

  2. 當多個動作作為鏈的一部分給出時,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.
  3. 然后, 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) 它正在測試兩個不同的東西:

  1. a.usesVoidMethod()調用b.voidMethod()
  2. 當依賴b拋出Exception時,被測對象a拋出RuntimeException

和 (c),它的名稱不正確。 它正在獨立測試上面的兩件事,它們是連續調用的事實是無關緊要的。

如果您刪除此測試方法的第一行,那么您將刪除正在模擬的b的行為。 然后測試將失敗,因為默認情況下對模擬的 void 方法調用不會執行任何操作; 即,不會有來自bException ,因此不會有來自a RuntimeException

你是對的,如果a被實際編碼,如果它被調用兩次,它會拋出一個RuntimeException ,那么就不需要模擬b 但這將比現在更不合理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM