当前位置: 首页 > 知识库问答 >
问题:

形成莫基托“语法”

利稳
2023-03-14

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方法的模式/组合用于哪些类型的测试用例(以及为什么)?提前谢谢!

共有3个答案

年良骏
2023-03-14
匿名用户

事实上,事情看起来比你想象的要简单得多

裁判: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方法())

柯梓
2023-03-14

莫奇托通常有几种做事方式。

我发现自己主要使用:

// 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>());
葛飞扬
2023-03-14

时/时返回时/时抛时/时语法有几个缺点。例如,

  • when/thenReturn的情况下,如果返回类型是带有通配符的泛型,并且希望返回相同类型的模拟,则无法避免编译警告
  • 不能将when/thenstrowwhen/then用于void方法
  • 你不能在莫基托间谍身上使用这些语法
  • 对于模拟对象、方法和参数的每个组合,只能在时调用一次,除非在模拟上调用reset
  • 当使用参数匹配器时,为模拟对象和方法的一个组合多次调用,可能会导致问题

我发现这些案例很难记住。因此,与其试图跟踪when/thenReturnwhen/thenThrowwhen/then语法何时会起作用和何时不会起作用,我更愿意完全避免它们,而采用doReturn/whendoThrow/whendoAnswer/when替代方案。这就是说,由于您偶尔需要doReturn/whendoThrow/whendoAnswer/when,并且您始终可以使用这些方法,因此学习如何使用when/thenReturnwhen/thenThrowwhen/then是没有意义的。

请注意,doReturndoThrowdoAnswer可以以与然后返回然后抛出相同的方式链接在一起。他们没有一个选项,可以在对doReturndoThrowdoAnswer的单个调用中返回多个值(或引发多个异常,或运行多个答案)。但我发现我很少需要这样做,所以这并不重要。

还有一个缺点:<代码> DORTEURN <代码>,我认为这是无关紧要的。您不会像使用when/thenReturn那样在编译时检查其参数类型。因此,如果参数类型错误,则在运行测试之前无法找到答案。坦白说,我不在乎。

综上所述,我已经使用Mockito两年多了,我认为一致使用doBackdoThrowdoACK是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正确地识别这种情况?