//interactions
mock.doSomething();
mock.doSomethingUnexpected();
//verification
verify(mock).doSomething();
//following will fail because 'doSomethingUnexpected()' is unexpected
verifyNoMoreInteractions(mock);
字符串 我在上面说“most-idiomatic”是因为该方法有自己的警告标签,它链接到Mockito创始人Szczepan Faber的博客文章"Should I worry about the unexpected?"(在different URL上仍然可见)。 verifyNoMoreInteractions()并不推荐用于所有测试方法。verifyNoMoreInteractions()是来自交互测试工具包的一个方便的Assert。仅在相关时使用它。滥用它会导致过度指定,较少维护测试。 简而言之,你应该有一个非常明确的理由来检查你的依赖项 * 没有做什么 * 或者你的被测系统 * 没有调用什么 *,而不是他们正在做什么和调用什么。如果你想避免不必要的RPC调用,你可以使用verifyNoMoreInteractions作为RPC对象,但不是(比如说)一个没有副作用的计算器。更好的是用never()或times(int)作为verify的参数来指定你的确切要求。 也就是说,有两种更不习惯的方法可以做到这一点:
java.lang.ClassCastException: org.mockito.codegen.Object$MockitoMock$191495750 cannot be cast to xxx.xxx.MyObject
型
错误输出示例
org.junit.ComparisonFailure: expected:<[DataRecordType{id=null, name='SomeRecord', pathTemplate='SomeTemplate'}]> but was:<[SmartNull returned by this unstubbed method call on a mock: dataRecordTypeRepository bean.getById(1L);]>
4条答案
按热度按时间gupuwyp21#
最惯用的方法是使用
verifyNoMoreInteractions
,如Mockito docs #8:字符串
我在上面说“most-idiomatic”是因为该方法有自己的警告标签,它链接到Mockito创始人Szczepan Faber的博客文章"Should I worry about the unexpected?"(在different URL上仍然可见)。
verifyNoMoreInteractions()
并不推荐用于所有测试方法。verifyNoMoreInteractions()
是来自交互测试工具包的一个方便的Assert。仅在相关时使用它。滥用它会导致过度指定,较少维护测试。简而言之,你应该有一个非常明确的理由来检查你的依赖项 * 没有做什么 * 或者你的被测系统 * 没有调用什么 *,而不是他们正在做什么和调用什么。如果你想避免不必要的RPC调用,你可以使用
verifyNoMoreInteractions
作为RPC对象,但不是(比如说)一个没有副作用的计算器。更好的是用never()
或times(int)
作为verify
的参数来指定你的确切要求。也就是说,有两种更不习惯的方法可以做到这一点:
mockingDetails(Object)
并迭代getInvocations()
的调用的总体日志。这应该会反射性地为您提供调用的完整列表。我很难想象这在测试中有什么用处,但它可能有助于清理模糊或缺乏文档的现有系统。型
当然,这是可行的,但你不仅违反了Mockito的核心原则之一,(默认情况下,mock是 nice,使用EasyMock对“nice”的定义),但是您也可以强迫自己只使用
doVerb
存根(doReturn
、doAnswer
等),因为对when(yourObject.doAnything())
的调用必然会在对when
的调用运行之前抛出该异常。熟悉Mockito的开发人员可能会说,这种倾向于异常的治疗方法比疾病更糟糕,并且可能只对临时诊断最混乱的遗留代码有用。
kulphzqa2#
我只是问自己同样的问题.使用ReturnsSmartNulls的解决方案将返回SmartNulls而不是null.所以它只对非void方法有意义,对吗?void方法呢?那些有副作用的方法?
在我看来,如果你想确保你的测试失败,当你的mock的一个方法被调用时,没有显式的行为定义(doXXX(...).when(...) mockito方法),你可以用一个自定义的默认答案来初始化你的mock,这个答案会抛出一个异常,或者更好的是.
例如,你可以在你的测试类中添加下面的类(或者如果你想在其他地方使用它,甚至可以使用前面提到的MockitoConfiguration类,这取决于你想要什么):
字符串
然后在你的setUp方法中使用这个假答案初始化你的mock:
型
不幸的是,此解决方案与@Mock annotation不兼容,@Mock annotation只接受org.mockito.Answers enum中的本地预定义答案作为参数。因此,这迫使您手动初始化setUp方法中的每个mock,spy,captor(RIP MockitoAnnotations.initMocks(this))
优点:
=>您必须定义您使用的所有内容(在测试或测试夹具中)
=>你不必进行验证来确保你的测试没有调用它不应该调用的方法。
缺点:
警告:这个解决方案并不保证你的mock被调用,它只是保证你没有存根的方法不会被调用。它也不能代替计数方法调用。
c3frrgcw3#
我发现的最佳答案是配置Mockito返回SmartNulls。
https://static.javadoc.io/org.mockito/mockito-core/2.6.9/org/mockito/Mockito.html#RETURNS_SMART_NULLS
这个实现在处理遗留代码时很有帮助。未存根的方法通常返回null。如果你的代码使用了未存根的调用返回的对象,你会得到一个NullPointerException。Answer的这个实现返回SmartPointer而不是null。SmartPointer给出了比NPE更好的异常消息,因为它指出了未存根的方法被调用的那一行。你只需点击堆栈跟踪。
您可以通过mock或默认方式来实现(可能会导致Spring等其他框架出现问题)。
手动
字符串
标注
型
设置为全局默认
配置类必须在这个包中。这可能会导致Spring的奇怪故障。
型
参见:https://solidsoft.wordpress.com/2012/07/02/beyond-the-mockito-refcard-part-1-a-better-error-message-on-npe-with-globally-configured-smartnull/
我在启用全局默认值时遇到了SpringBootRepositories和@MockBean的问题:
型
错误输出示例
型
flvlnr444#
如果您试图跟踪流,您可以使用Mockito验证来检查是否已进行某些调用。
字符串
你也可以用times来验证某个呼叫是否必须被准确地打几次。
型
让单元测试变得复杂并不是一个好的做法。一次只测试一小部分代码。