我有一些模拟对象可能会被传递一些,最终可能会相当复杂。如果Mockito在发生意外呼叫时会导致失败,那么我该如何获得Mockito?
我想让Mockito为模拟的每个调用输出一个日志,或者我希望在发生意外调用时它会失败,以便可以遍历这些调用并设置适当的响应。
我该如何做到这一点?
我有一些模拟对象可能会被传递一些,最终可能会相当复杂。如果Mockito在发生意外呼叫时会导致失败,那么我该如何获得Mockito?
我想让Mockito为模拟的每个调用输出一个日志,或者我希望在发生意外调用时它会失败,以便可以遍历这些调用并设置适当的响应。
我该如何做到这一点?
这样做的最惯用的方法是用verifyNoMoreInteractions
,如Mockito docs #8:
//interactions
mock.doSomething();
mock.doSomethingUnexpected();
//verification
verify(mock).doSomething();
//following will fail because 'doSomethingUnexpected()' is unexpected
verifyNoMoreInteractions(mock);
我说:“最地道”上面,因为这种方法有它自己的警告标签,可链接到博客文章由Mockito发起人Szczepan Faber提供的"Should I worry about the unexpected?"。
verifyNoMoreInteractions()
不建议在每种测试方法中使用。verifyNoMoreInteractions()
是交互测试工具包的一个便利的断言。只有在相关时才使用它。滥用它导致过分指定,较少维护测试。
总之,你应该有一个非常明确的理由来检查你的依赖是没有做或您的系统下测试是什么没有要求,而不是他们在做什么和电话。如果你想避免不必要的RPC调用,你可以使用verifyNoMoreInteractions
作为RPC对象,但是不要(比如说)没有副作用的计算器。更好的是以never()
或times(int)
作为参数verify
来指定您的确切要求。
也就是说,这样做有两个偶数不太习惯的方式:
您可以使用mockingDetails(Object)
并通过getInvocations()
迭代进行呼叫的整体日志。这应该反射性地给你一个调用的完整列表。我很难想象这在测试中会如何有用,但它可能对清除模糊或者记录不完整的现有系统有用。
您可以使模拟的默认操作引发异常,这意味着如果任何人调用了一些未被存根的东西,测试将立即失败。
// untested pseudocode
YourObject yourObject = Mockito.mock(YourObject.class, withSettings()
.defaultAnswer(invocation -> {
throw new UnsupportedOperationException(invocation.toString());
}));
当然,这会工作,但你不仅(使用EasyMock's definition of "nice"mocks are nice by default)违反的的Mockito的核心原则之一,但你也想使用doVerb
(doReturn
,doAnswer
强迫自己只存根等等),因为when(yourObject.doAnything())
的呼叫必然会在when
的呼叫甚至运行之前抛出该异常。
熟悉Mockito的开发人员可能会说这种易发生异常的治疗比疾病更糟,并且可能仅用于临时诊断最混乱的遗留代码。
如果您试图追踪流量,您可以使用Mockito验证来检查是否进行了某个呼叫。
verify(yourMockedObject).yourMethod();
您还可以使用次数来验证某个呼叫是否必须完成某些次数。
verify(yourMockedObject, times(4)).yourMethod();
使单元测试变得复杂不是一个好习惯。尝试一次只测试一小部分代码。
为什么不只是验证模拟? – Mureinik