這不是Mockito可以輕鬆做到的事情。 EasyMock的默認嚴格模擬確保(1)意外的交互立即失敗,(2)所有預期的交互發生;除了verifyNoMoreInteractions
(這不會立即失敗,而是在測試結束時),Mockito也沒有設置。這是一個philosophical design decision on Mockito's part,並參見this thread Mockito發起人進一步討論它。
事實上,的Mockito的when
語法取決於它允許意想不到的互動,因爲意想不到的互動告訴的Mockito該方法被調用:
when(mockFoo.someMethod()).thenReturn(someValue);
// ^^^^^^^^^^^^^^^^^^^^ Java calls this first to get an argument for when,
// which is how Mockito knows which method to stub:
// it's always the last one called.
EasyMock的嘲笑是寬容意外通話費的命名「不錯的嘲笑」; Mockito的一大賣點是默認情況下mock很好,因此它們通常能容忍與被測試行爲無關的調用。這確實會使調試變得更加困難,因爲Mockito不會像EasyMock那樣立即在意外的交互中失敗,但它也會使測試更加脆弱 - 更可能的是,安全更改仍然會因爲EasyMock模擬而打破測試有一個意外的電話。 在繼續進行之前,請與您的團隊確認他們會很滿意您的選擇:對於Mockito而言,嚴格的模擬語義是非常不尋常的,而且可能像框架更改那樣存在一些破壞性假設。 (到這一點,看到替代後,他們可能會讓你畢竟使用了EasyMock!)
要的Mockito效仿嚴格嘲笑,你就需要設置測試失敗默認的回答,並且僅使用doVerb
方法(doAnswer
,doReturn
,doThrow
等)建立您的正確行爲。此語法爲Mockito提供了警告,它需要停用您的存根行爲。要創建默認的答案,您可以爲單個方法(首選)或單個模擬中的所有方法設置行爲。
public class ThrowingAnswer extends Answer<Object> {
@Override public Object answer(InvocationOnMock invocation) {
throw new AssertionError("Unexpected invocation: " + invocation);
}
}
// apply to the entire object:
YourObject yourObject = Mockito.mock(YourObject.class, new ThrowingAnswer());
// or per-method:
YourObject yourObject = Mockito.mock(YourObject.class);
doAnswer(new ThrowingAnswer()).when(yourObject).scaryMethod(any());
的Mockito總是在最後定義匹配鏈返回的行爲,並且將只使用默認的答案,如果沒有連鎖的比賽,所以你應該能夠定義任意數量鏈與doVerb
方法來重寫該行爲。
不確定,但也許定義一個自定義規則會解決它。 –
我在想:通常人們比EasyMock更喜歡Mokito,因爲他們可以像你在第一行中那樣寫下他們的代碼。如果你喜歡EasyMock做事的方式;方法你不只是使用EasyMock? – GhostCat
@JägermeisterEasyMock是可行的,但在基於團隊的環境中,人們喜歡爲了一致性目的而設置一個通用框架。只是希望有可能通過Mockito實現它。 – Nathan