形成莫米托"grammars"



Mockito似乎是一个非常好的Java存根/嘲笑框架。唯一的问题是我找不到任何关于使用API的最佳方法的具体文档。测试中常用的方法包括:

doXXX(???) : Stubber
when(T) : OngoingStubbing
then(T) : OngoingStubbing
verify(???) : T
given(T) : BDDOngoingStubbing
willXXX(???) : BDDStubber

当你在实践中看到Mockito的例子时,你会看到这样的代码:

when(yourMethod()).thenReturn(5);

从我读过的所有文件中,我发现了几个";图案";Mockito的";语法;通过菊花链将这些方法调用连接在一起获得,就像上面的例子一样。我发现的一些常见模式是:

何时/然后:何时(yourMethod())。然后返回(5);

Given/Will:Given(yourMethod()).willThrow(OutOfMemoryException.class);

Do/When:doReturn(7).When(yourMock.fizhBuzz());

Will/Given/Do:willReturn(any()).gived(yourMethod()).doNothing();

Verify/Do:Verify(yourMethod()).doThrow(SomeException.class);

我所困扰的是如何选择正确的方法调用模式/组合来为我的测试用例建模。似乎你可以将这些菊花链连接在一起,形成似乎无穷无尽的组合,我不确定什么模式适合哪个问题。

Mockito的一些专家能否帮助我们了解Mockito方法的哪些模式/组合用于哪些类型的测试用例(以及为什么)?提前感谢!

when/thenReturnwhen/thenThrowwhen/then语法有几个缺点。例如,

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

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

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

doReturn还有一个缺点,我认为它微不足道。您不会像使用when/thenReturn那样在编译时检查其参数的类型。因此,如果您的参数类型错误,那么在运行测试之前,您不会发现。坦率地说,我不在乎。

总之,我已经使用Mockito两年多了,我认为持续使用doReturndoThrowdoAnswer是Mockito的最佳实践。其他Mockito用户不同意。

Mockito通常有几种做事方法。

我发现自己主要使用:

// 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?"给定"one_answers"将要"构造在最新版本(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>());

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

参考:http://static.javadoc.io/org.mockito/mockito-core/2.7.12/org/mockito/Mockito.html

验证

为了使用Mockito,您需要了解Mockito的一个基本哲学:Stubbing和Verification是分开的。因此,您提到的"Verify/Do"实际上是在做"Verification"工作,而其他4个"grammars"则用于存根。Stubbing定义了mock对象在不同情况下的反应。验证是为了确保在之前对被测系统(SUT)的调用中,mock被按预期调用。

何时/然后,给定/将

然后是"何时"one_answers"给予"家庭。您可以简单地将它们视为彼此的别名。Mockito 1.8.x中添加了"Given"家族,使其看起来更符合BDD实践。

DoXxx

在正常情况下,我们主要使用when(xxx).then(...)(和given(...).will(...))。然而,在某些情况下,语法不起作用。最明显的情况是当存根方法的返回类型为void时。在这种情况下,when(mockObj.voidMethod()).thenThrow(anException)不会编译。作为一种变通方法,将创建Do/When的替代语法,这样您就可以将前一行写为doThrow(anException).when(mockObj.voidMethod())

相关内容

  • 没有找到相关文章

最新更新