簡體   English   中英

Mockito - doReturn() 和 when() 之間的區別

[英]Mockito - difference between doReturn() and when()

我目前正在使用 Mockito 在 Spring MVC 應用程序中模擬我的服務層對象,我想在其中測試我的控制器方法。 然而,當我一直在閱讀 Mockito 的細節時,我發現方法doReturn(...).when(...)等效於when(...).thenReturn(...) 所以,我的問題是讓兩種方法做同樣的事情有什么意義,或者doReturn(...).when(...)when(...).thenReturn(...) ?

任何幫助將不勝感激。

存根的兩種語法大致相同。 但是,您始終可以使用doReturn/when進行存根; 但有些情況下您不能使用when/thenReturn 存根 void 方法就是這樣一種方法。 其他包括與 Mockito 間諜一起使用,並多次使用相同的方法。

when/thenReturn給你的一件事是在編譯時對你返回的值進行類型檢查,而doReturn/when沒有。 但是,我相信這幾乎沒有任何價值 - 如果您的類型錯誤,您會在運行測試后立即發現。

我強烈建議只使用doReturn/when 當一種語法可以學習時,學習兩種語法是沒有意義的。

您可能希望參考我在Forming Mockito “grammars” 中的回答 - 對一個非常密切相關的問題的更詳細的回答。

如果您使用被監視的對象(用@Spy注釋)而不是模擬(用@Mock注釋),兩種方法的行為會有所不同:

  • when(...) thenReturn(...)在返回指定值之前進行真正的方法調用 所以如果被調用的方法拋出一個異常,你必須處理它/模擬它等等。當然你仍然得到你的結果(你在thenReturn(...)定義的)

  • doReturn(...) when(...)根本不調用該方法

示例:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

測試:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");

Mockito javadoc 似乎說明了為什么在無法使用 Mockito.when(Object) 的極少數情況下使用doReturn()而不是when()使用 doReturn()。

請注意,始終建議將 Mockito.when(Object) 用於存根,因為它是參數類型安全的且更具可讀性(尤其是在存根連續調用時)。

以下是 doReturn() 派上用場的罕見情況:

1.當spy真正的對象,在spy上調用真正的方法會帶來副作用

List list = new LinkedList(); List spy = spy(list);

//不可能:真正的方法被調用所以spy.get(0)拋出IndexOutOfBoundsException(列表還為空)

when(spy.get(0)).thenReturn("foo");

//您必須使用 doReturn() 進行存根: doReturn("foo").when(spy).get(0);

2.覆蓋之前的異常存根:

when(mock.foo()).thenThrow(new RuntimeException());

//不可能:調用異常存根的 foo() 方法因此拋出 RuntimeException。 when(mock.foo()).thenReturn("bar");

//您必須使用 doReturn() 進行存根:

doReturn("bar").when(mock).foo(); 以上場景顯示了 Mockito 優雅語法的權衡。 但請注意,這種情況非常罕見。 監視應該是零星的,並且覆蓋異常存根是非常罕見的。 更不用說一般來說,覆蓋存根是一種潛在的代碼異味,指出存根過多。

繼續這個答案,還有另一個區別,如果您希望您的方法返回不同的值,例如第一次調用,第二次調用等時,那么您可以傳遞值,例如...

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

因此,當在同一測試用例中調用該方法時,它將返回 false,然后再次返回 false,最后返回 true。

后一種替代方法用於返回void模擬方法。

請看一下,例如,這里: How to make mock to void methods with mockito

“mock”可以模擬對象而不是創建它;“spy”可以創建具有實際參數的實際對象。 當我們進行單元測試時,我們經常使用它們。 但'when(xxx).thenReturn(xxx)'用於模擬和'doReturn(xxx).when(xxx)'用於間諜。

暫無
暫無

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

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