Mockito似乎是一个非常好的Java存根/模拟框架。唯一的问题是我找不到任何关于使用API的最佳方法的具体文档。测试中使用的常用方法包括:
doXXX(???) : Stubber
when(T) : OngoingStubbing
then(T) : OngoingStubbing
verify(???) : T
given(T) : BDDOngoingStubbing
willXXX(???) : BDDStubber
当您在实践中看到Mockito的示例时,您会看到如下代码:
when(yourMethod()).thenReturn(5);
从我读过的所有文档中,我已经识别了几个Mockito“语法”的“模式”,这些“语法”是通过将这些方法调用像上面的示例一样链接在一起而获得的。我发现的一些常见模式有:
当/然后:当(你的方法())。
gived/Will:gived(yourMethod())。willThrow(OutOfMemoryException.class);
做/当:do返回(7)。当(你的ock.fizz嗡嗡声());
将/给定/做:将返回(any())。
Verify/Do:Verify(yourMethod())。doThrow(SomeException.class);
我最头疼的是如何选择正确的方法调用模式/组合来模拟我的测试用例。看起来你们可以用菊花链把这些东西连在一起,看起来没完没了,我不确定哪种模式适合哪个问题。
一些Mockito大师能否帮助阐明哪些Mockito方法的模式/组合用于哪些类型的测试用例(以及为什么)?提前谢谢!
匿名用户
事实上,事情看起来比你想象的要简单得多
裁判:http://static.javadoc.io/org.mockito/mockito-core/2.7.12/org/mockito/Mockito.html
核实:
为了使用Mockito,你需要理解Mockito的一个基本哲学:存根和验证是分开的。所以,你说的“验证/做”,其实是在做“验证”的工作,而其他4个“语法”,则是为了存根。存根定义了模拟对象在不同情况下的反应。验证是为了确保在之前对被测试系统(SUT)的调用中,模拟对象按预期被调用。
当/那时,给定/将:
然后是“何时”和“给予”家庭。您可以简单地将它们视为彼此的别名。Mockito 1.8中增加了“给定”族。以使其看起来更符合BDD实践。
DoXxx:
在正常情况下,我们主要使用当(xxx).然后(...)
(和给定(...). will(...)
)。然而,在某些情况下,语法不起作用。最明显的情况是存根方法的返回类型为无效。在这种情况下,当(mockObj.void方法()). thenThrow(anExc0019)不编译时。作为一种解决方案,创建了一个替代语法Do/Time,因此您可以将前一行写成doThrow(anExc0019). time(mockObj.void方法())
莫奇托通常有几种做事方式。
我发现自己主要使用:
// Setup expectations
when(object.method()).thenReturn(value);
when(object.method()).thenThrow(exception);
doThrow(exception).when(object.voidMethod());
// verify things
verify(object, times(2)).method();
verify(object, times(1)).voidMethod();
我发现我可以用这三种电话完成95%的工作。
另外,您使用的Mockito版本是什么?最新版本(1.9.0)中不存在“给定”和“将”构造
但是,在某些情况下,我希望返回值或异常响应输入。在这种情况下,可以使用Answer接口检查方法参数并返回适当的值。
public class ReturnFirstArg<T> implements Answer<T> {
public T answer(InvocationOnMock invocation) {
return invocation.getArguments()[0];
}
}
when(object.method(7)).thenAnswer(new ReturnFirstArg<Integer>());
时/时返回
、时/时抛
和时/时
语法有几个缺点。例如,
when/thenReturn
的情况下,如果返回类型是带有通配符的泛型,并且希望返回相同类型的模拟,则无法避免编译警告
when/thenstrow
和when/then
用于void方法
,除非在模拟上调用reset
当使用参数匹配器时,为模拟对象和方法的一个组合多次调用,可能会导致问题
我发现这些案例很难记住。因此,与其试图跟踪
when/thenReturn
、when/thenThrow
和when/then
语法何时会起作用和何时不会起作用,我更愿意完全避免它们,而采用doReturn/when
、doThrow/when
和doAnswer/when
替代方案。这就是说,由于您偶尔需要doReturn/when
、doThrow/when
和doAnswer/when
,并且您始终可以使用这些方法,因此学习如何使用when/thenReturn
、when/thenThrow
和when/then
是没有意义的。
请注意,
doReturn
、doThrow
和doAnswer
可以以与然后返回
、然后抛出
相同的方式链接在一起。他们没有一个选项,可以在对doReturn
、doThrow
和doAnswer
的单个调用中返回多个值(或引发多个异常,或运行多个答案)。但我发现我很少需要这样做,所以这并不重要。
还有一个缺点:<代码> DORTEURN <代码>,我认为这是无关紧要的。您不会像使用
when/thenReturn
那样在编译时检查其参数类型。因此,如果参数类型错误,则在运行测试之前无法找到答案。坦白说,我不在乎。
综上所述,我已经使用Mockito两年多了,我认为一致使用
doBack
、doThrow
和doACK
是Mockito的最佳实践。其他Mockito用户不同意。
我对莫基托有疑问。我想测试这个简单的类: 我写了这个简单的测试: 此测试运行时没有错误。我等待它没有编译,因为没有任何对userService方法的调用…
Mockito——我知道间谍在对象上调用实际方法,而模拟在双对象上调用方法。此外,除非有代码气味,否则要避免间谍。然而,间谍是如何工作的?我应该在什么时候使用他们?它们与模拟有什么不同?
为什么Mockito会吞噬堆栈痕迹?例如,如果我有一个 和一个测试,例如 抛出的异常看起来总是 (这里提供的示例只是一个简化--我要处理更多的间接、类等等。我不能让Mockito吞噬部分模拟堆栈跟踪的关键部分……)
试图将我的项目从Java 11更新到Java 17,在一个特定测试中,Mockito出现了一个意外错误。 投掷 不知道为什么Mockito这次考试不及格。
测试类别 测试类别 详图搁置器 当我尝试模拟方法HistoryFromStrgyTable()的数据时,它实际上是在调用HistoryFromStrgyTable(),而不是从mockHistoryFromStrgyTable()获取数据。 我的测试用例在这一行失败了 谁能帮我一下吗。我不明白怎么了。我还将方法mockHistoryFromStrgyTable()从private更改为public
现在,发生的事情似乎是,当field为0时,Mockito在第1行捕获对参数的引用。然后,在下一行中,该字段将增加到1,并一直保持到第3行,在第3行中进行验证。因此,Mockito错误地认为有两次调用,而第一次调用显然是 我如何指示Mockito正确地识别这种情况?