目前,我正在使用Mockito在Spring MVC应用程序中模拟我的服务层对象,在该应用程序中我想测试控制器方法。但是,正如我一直在阅读Mockito的细节时,我发现了这些方法 doReturn(...).when(...) 等同于 when(...).thenReturn(...). 。因此,我的问题是,有两种做同一件事的方法是什么意义 doReturn(...).when(...)when(...).thenReturn(...)?

任何帮助,将不胜感激。

有帮助吗?

解决方案

固执的两个语法大致相等。但是,你可以 总是 利用 doReturn/when 固定;但是在某些情况下 不能 利用 when/thenReturn. 。固执空隙方法就是一种。其他包括与Mockito间谍一起使用,并多次使用相同的方法。

一件事 when/thenReturn 给你那个 doReturn/when 不,是在编译时返回的价值的类型检查。但是,我相信这几乎没有价值 - 如果您的类型错误,您就可以在进行测试后立即找到答案。

我强烈建议只使用 doReturn/when. 。学习两个语法是没有意义的。

您可能希望参考我的答案 形成摩根托语“语法” - 对一个非常相关的问题的更详细的答案。

其他提示

如果您使用间谍对象,则两种方法的行为都不同(用注释 @Spy)而不是模拟(注释 @Mock):

  • when(...) thenReturn(...) 做一个真正的方法调用 就在指定值之前返回。因此,如果调用方法引发异常,则必须处理 /模拟它等。当然,您仍然得到结果(您定义的内容 thenReturn(...))

  • doReturn(...) when(...) 根本不调用该方法.

例子:

public class MyClass {
     protected String methodToBeTested() {
           return anotherMethodInClass();
     }

     protected String anotherMethodInClass() {
          throw new NullPointerException();
     }
}

测试:

@Spy
private MyClass myClass;

// ...

// would work fine
doReturn("test").when(myClass).anotherMethodInClass();

// would throw a NullPointerException
when(myClass.anotherMethodInClass()).thenReturn("test");

Mockito Javadoc似乎说明了为什么使用 doReturn() 代替 when()在极少数情况下,当您无法使用Mockito.时(对象)时,请使用Doreturn()。

当心始终建议使用Mockito.时(对象)进行固执,因为它是参数类型安全性并且更可读性(尤其是连续呼叫时)。

以下是Doreturn()方便的罕见情况:

1. 当监视真实物体并在间谍上调用真实方法时会带来副作用

List list = new LinkedList(); List spy = spy(list);

//不可能:真实方法被称为spy.get(0)抛出indexoutofboundsexception(列表尚未为空)

when(spy.get(0)).thenReturn("foo");

//您必须使用doreturn()进行固定: doReturn("foo").when(spy).get(0);

2. 覆盖以前的例外费集:

when(mock.foo()).thenThrow(new RuntimeException());

//不可能:称为foo()方法的异常插入,因此抛出了RuntimeException。 when(mock.foo()).thenReturn("bar");

//您必须使用doreturn()进行固定:

doReturn("bar").when(mock).foo(); 上面的方案显示了Mockito优雅语法的权衡。请注意,这种情况非常罕见。间谍应该是零星的,并且重大的异常插入非常罕见。更不用说一般而言的超级固执是一种潜在的代码气味,指出了太多的固执。

继续 这个答案, ,还有另一个区别是,如果您希望方法返回不同的值,例如第一次调用时,第二次调用等,则可以传递值,例如...

PowerMockito.doReturn(false, false, true).when(SomeClass.class, "SomeMethod", Matchers.any(SomeClass.class));

因此,当该方法在同一测试案例中调用时,它将返回false,然后它将再次返回false,最后是正确的。

后一个替代方法用于返回的模拟方法的方法 void.

请在这里看看:如何使用Mockito对空隙方法进行模拟

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top