问题

我目前正在使用Mockito来模拟Spring MVC应用程序中的服务层对象,我想在其中测试我的Controller方法。但是,正如我一直在阅读Mockito的细节,我发现方法doReturn(...).when(...)相当于when(...).thenReturn(...)。所以,我的问题是,有两种方法可以做同样的事情,或者是什么是1914146896和when(...).thenReturn(...)之间的细微差别?

任何帮助,将不胜感激。


#1 热门回答(133 赞)

存根的两种语法大致相同。但是,你管道使用doReturn/when进行存根;但有些情况下你不能使用when/thenReturn。挖空虚方法就是其中之一。其他包括与Mockito间谍一起使用,并且不止一次地使用相同的方法。

在编译时,对于你所返回的值的类型检查,有一件事情,即对你来说,那就是46524242。但是,我认为这几乎没有任何价值 - 如果你的类型错了,你会在你运行测试后立即发现。

我强烈建议仅使用doReturn/when。当一个人学习时,学习两种语法是没有意义的。

你可以参考我的答案Forming Mockito "grammars"-一个非常密切相关的问题的更详细的答案。


#2 热门回答(114 赞)

如果你使用间谍对象(注释为@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");

#3 热门回答(6 赞)

Mockito javadoc似乎告诉为什么使用doReturn()而不是when()使用doReturn()在那些罕见的情况下你不能使用Mockito.when(Object)。

请注意,Mockito.when(Object)始终建议用于存根,因为它是参数类型安全且更具可读性(特别是在存根连续调用时)。以下是doReturn()派上用场的罕见场合:1。当窥探真实对象并在间谍上调用真实方法时会产生副作用List list = new LinkedList();列出spy = spy(列表); //不可能:调用真正的方法,因此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。当(mock.foo())thenReturn( "条")。 //你必须使用doReturn()进行存根:doReturn("bar")。when(mock).foo();以上场景显示了Mockito优雅语法的权衡。请注意,这些场景非常罕见。间谍应该是零星的,而且压倒一切的例外情况非常罕见。更不用说一般来说,覆盖存根是一种潜在的代码气味,指出了过多的存根。


原文链接