2016-03-24 70 views
3

驗證是否預期的方法已在運行的Mockito通常是這樣的:我可以在實例化時間設置Mockito模擬與期望(驗證)嗎?

when(mockFoo.someMethod()).thenReturn(someValue); 
// run test 
verify(mockFoo, times(n)).someMethod(); 

有沒有辦法對我來說,在我創建模擬時指定的驗證。在類似的EasyMock我可以這樣做:

mockFoo = EasyMock.createMock(Foo.class); 
EasyMock.expect(mockFoo.someMethod()).times(n).andReturn(someValue); 
// then run test 

我的使用情況是,我有一個常用複用的測試依賴,我想嘲笑(在doesFooMethodAndReturnBar5Times嘲笑),但與我的Mockito沒有辦法對其執行驗證。

+0

不確定,但也許定義一個自定義規則會解決它。 –

+0

我在想:通常人們比EasyMock更喜歡Mokito,因爲他們可以像你在第一行中那樣寫下他們的代碼。如果你喜歡EasyMock做事的方式;方法你不只是使用EasyMock? – GhostCat

+0

@JägermeisterEasyMock是可行的,但在基於團隊的環境中,人們喜歡爲了一致性目的而設置一個通用框架。只是希望有可能通過Mockito實現它。 – Nathan

回答

3

這不是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,doReturndoThrow等)建立您的正確行爲。此語法爲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方法來重寫該行爲。

相關問題