Java Mockito : doAnswer Vs thenReturn

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36615330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 18:29:13  来源:igfitidea点击:

Mockito : doAnswer Vs thenReturn

javamockito

提问by Rajkumar Thambu

I am using Mockito for service later unit testing. I am confused when to use doAnswervs thenReturn.

我正在使用 Mockito 进行后续单元测试。我很困惑何时使用doAnswervs thenReturn

Can anyone help me in detail? So far, I have tried it with thenReturn.

谁能帮我详细点?到目前为止,我已经尝试过使用thenReturn.

回答by Roland Weisleder

You should use thenReturnor doReturnwhen you know the return value at the time you mock a method call. This defined value is returned when you invoke the mocked method.

当您在模拟方法调用时知道返回值时,您应该使用thenReturnor doReturn。当您调用模拟方法时,将返回此定义的值。

thenReturn(T value)Sets a return value to be returned when the method is called.

thenReturn(T value)设置调用方法时要返回的返回值。

@Test
public void test_return() throws Exception {
    Dummy dummy = mock(Dummy.class);
    int returnValue = 5;

    // choose your preferred way
    when(dummy.stringLength("dummy")).thenReturn(returnValue);
    doReturn(returnValue).when(dummy).stringLength("dummy");
}

Answeris used when you need to do additional actions when a mocked method is invoked, e.g. when you need to compute the return value based on the parameters of this method call.

Answer当您需要在调用模拟方法时执行其他操作时使用,例如,当您需要根据此方法调用的参数计算返回值时。

Use doAnswer()when you want to stub a void method with generic Answer.

Answer specifies an action that is executed and a return value that is returned when you interact with the mock.

使用doAnswer()时要与存根通用空隙的方法Answer

Answer 指定执行的操作和与模拟交互时返回的返回值。

@Test
public void test_answer() throws Exception {
    Dummy dummy = mock(Dummy.class);
    Answer<Integer> answer = new Answer<Integer>() {
        public Integer answer(InvocationOnMock invocation) throws Throwable {
            String string = invocation.getArgumentAt(0, String.class);
            return string.length() * 2;
        }
    };

    // choose your preferred way
    when(dummy.stringLength("dummy")).thenAnswer(answer);
    doAnswer(answer).when(dummy).stringLength("dummy");
}

回答by aldok

doAnswerand thenReturndo the same thing if:

doAnswer并在以下情况下thenReturn做同样的事情:

  1. You are using Mock, not Spy
  2. The method you're stubbing is returning a value, not a void method.
  1. 您使用的是 Mock,而不是 Spy
  2. 您存根的方法正在返回一个值,而不是一个 void 方法。

Let's mock this BookService

让我们模拟这个 BookService

public interface BookService {
    String getAuthor();
    void queryBookTitle(BookServiceCallback callback);
}

You can stub getAuthor() using doAnswerand thenReturn.

您可以使用doAnswer和存根 getAuthor() thenReturn

BookService service = mock(BookService.class);
when(service.getAuthor()).thenReturn("Joshua");
// or..
doAnswer(new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        return "Joshua";
    }
}).when(service).getAuthor();

Note that when using doAnswer, you can't pass a method on when.

请注意,在使用时doAnswer,您不能在 上传递方法when

// Will throw UnfinishedStubbingException
doAnswer(invocation -> "Joshua").when(service.getAuthor());

So, when would you use doAnswerinstead of thenReturn? I can think of two use cases:

那么,你什么时候使用doAnswer而不是thenReturn?我可以想到两个用例:

  1. When you want to "stub" void method.
  1. 当你想“存根”void 方法时。

Using doAnswer you can do some additionals actions upon method invocation. For example, trigger a callback on queryBookTitle.

使用 doAnswer 您可以在方法调用时执行一些附加操作。例如,触发对 queryBookTitle 的回调。

BookServiceCallback callback = new BookServiceCallback() {
    @Override
    public void onSuccess(String bookTitle) {
        assertEquals("Effective Java", bookTitle);
    }
};
doAnswer(new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        BookServiceCallback callback = (BookServiceCallback) invocation.getArguments()[0];
        callback.onSuccess("Effective Java");
        // return null because queryBookTitle is void
        return null;
    }
}).when(service).queryBookTitle(callback);
service.queryBookTitle(callback);
  1. When you are using Spy instead of Mock
  1. 当您使用 Spy 而不是 Mock 时

When using when-thenReturn on Spy Mockito will call real method and then stub your answer. This can cause a problem if you don't want to call real method, like in this sample:

在 Spy Mockito 上使用 when-thenReturn 时,会调用真正的方法,然后存根您的答案。如果您不想调用真正的方法,这可能会导致问题,例如在此示例中:

List list = new LinkedList();
List spy = spy(list);
// Will throw java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
when(spy.get(0)).thenReturn("java");
assertEquals("java", spy.get(0));

Using doAnswer we can stub it safely.

使用 doAnswer 我们可以安全地存根。

List list = new LinkedList();
List spy = spy(list);
doAnswer(invocation -> "java").when(spy).get(0);
assertEquals("java", spy.get(0));

Actually, if you don't want to do additional actions upon method invocation, you can just use doReturn.

实际上,如果您不想在方法调用时执行其他操作,则可以使用doReturn.

List list = new LinkedList();
List spy = spy(list);
doReturn("java").when(spy).get(0);
assertEquals("java", spy.get(0));