[英]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.