这不是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