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

mockito-doReturn()和when()之间的差异

劳麒
2023-03-14

我目前正在使用Mockito在一个spring MVC应用程序中模拟我的服务层对象,我想在其中测试我的控制器方法。但是,由于我一直在阅读Mockito的细节,我发现doReturn(...).when(...)方法等同于when(...).thenReturn(...)。所以,我的问题是,有两个方法做同样的事情有什么意义,或者doReturn(...).when(...)when(...).thenReturn(...)之间有什么微妙的区别?

如有任何帮助,我们将不胜感激。

共有3个答案

葛雪松
2023-03-14

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

注意,总是建议mockito.when(Object)进行截短,因为它是参数类型安全的,并且更易读(特别是在截短连续调用时)。

以下是doReturn()派上用场的几种罕见情况:

1.当刺探真实对象并对间谍调用真实方法带来副作用时

列表列表=新建LinkedList();List spy=spy(列表);

//Impossible:调用real方法,因此Spy.Get(0)抛出IndexOutOfBoundsException(列表仍为空)

当(spy.get(0)).thenreturn(“foo”);

//必须使用doReturn()进行截尾:doReturn(“foo”).when(spy).get(0);

2.重写以前的异常截除:

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

//Impossible:调用exception-stubed foo()方法,因此抛出RuntimeException。when(mock.foo()).thenreturn(“bar”);

//必须使用doReturn()进行截尾:

doReturn(“bar”).when(mock).foo();以上场景显示了mockito优雅语法的折衷。不过,请注意,这种情况非常少见。间谍活动应该是零星的,并且是压倒一切的例外--拦截是非常罕见的。更不用说,通常情况下,重写stubbing是一种潜在的代码气味,它指出了太多的stubbing。

仲璞瑜
2023-03-14

如果使用间谍对象(用@spy批注)而不是模拟对象(用@mock批注),则这两种方法的行为不同:

>

  • 当(...)thenReturn(...)在返回指定值之前执行一个实际的方法调用。因此,如果被调用的方法抛出异常,您必须处理它/模拟它等。当然,您仍然得到您的结果(您在thenreturn(...)中定义的)

    doReturn(...)当(...)根本不调用该方法。

    示例:

    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");
    

  • 柳晔
    2023-03-14

    短发的两种语法大致等价。但是,始终可以使用doreturn/when进行截尾;但在某些情况下,当/thenreturn时不能使用。抽除void方法就是这样一种方法。其他方法包括与Mockito间谍一起使用,以及多次使用相同的方法。

    when/thenreturn提供给您的一件事情是在编译时对返回的值进行类型检查,而doreturn/when没有这样做。然而,我相信这几乎没有任何价值--如果您搞错了类型,您会在运行测试时发现。

    我强烈建议只使用doreturn/when。学两个语法,一个就可以了,这是没有意义的。

    您可能希望参考我在“形成Mockito”语法“上的回答--对一个非常密切相关的问题的更详细的回答。

     类似资料:
    • 问题内容: 我目前正在使用在应用程序中模拟我的服务层对象的过程中,我想在其中测试我的方法。但是,当我阅读Mockito的细节时,我发现这些方法等效于。所以,我的问题是什么是有两个方法,做同样的事情或之间有什么细微的区别点和? 任何帮助,将不胜感激。 问题答案: 存根的两种语法大致相同。但是,你始终可以将其用于存根。但是在某些情况下你不能使用。废除无效方法就是这样的一种。其他方法包括与间谍一起使用,

    • 这是我的实际服务方法。在测试时,它给我的变量为空。用户和响应 我试图写一个测试用例和模拟方法findByEmail()和保存(),但同时嘲笑我没有收到用户对象在返回中提到的thenback()和doback()。 有人能帮忙吗。

    • 看起来HttpClient及其子类有问题。

    • 当使用间谍对象作为测试对象时,如果我们不想在我们正在测试的方法中调用嵌套方法,这些方法中的哪一个(doReport-time或whing-thenBack)可以用来模拟这些嵌套方法?有没有办法避免在我们将要测试的方法中调用真正的方法?

    • 问题内容: 很快就有两个相等运算符:double equals( )和Triple equals( ),两者之间有什么区别? 问题答案: 简而言之: 操作员检查其实例值是否相等, 操作员检查引用是否指向同一实例, 长答案: 类是引用类型,可能有多个常量和变量在幕后引用类的同一单个实例。类引用保留在运行时堆栈(RTS)中,其实例保留在内存的堆区域中。当您控制平等时, 这意味着它们的实例是否彼此相等。