2016-03-24 93 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方法来重写该行为。

相关问题