Mocking Void Methods with Mockito – 用Mockito嘲弄虚空方法

最后修改: 2017年 10月 29日

中文/混合/英文(键盘快捷键:t)

1. Overview

1.概述

In this short tutorial, we focus on mocking void methods with Mockito.

在这个简短的教程中,我们主要讨论用Mockito来模拟void方法。

As with other articles focused on the Mockito framework (such as Mockito Verify, Mockito When/Then, and Mockito’s Mock Methods), the MyList class shown below will be used as the collaborator in test cases.

与其他关注Mockito框架的文章一样(如Mockito验证Mockito When/ThenMockito的模拟方法),下面所示的MyList类将作为测试案例中的协作者。

We’ll add a new method for this tutorial:

我们将为本教程添加一个新方法。

public class MyList extends AbstractList<String> {
 
    @Override
    public void add(int index, String element) {
        // no-op
    }
}

2. Simple Mocking and Verifying

2.简单的嘲弄和验证

Void methods can be used with Mockito’s doNothing(), doThrow(), and doAnswer() methods, making mocking and verifying intuitive:

Void方法可与Mockito的doNothing()doThrow()和doAnswer()方法一起使用,使嘲弄和验证变得直观。

@Test
public void whenAddCalledVerified() {
    MyList myList = mock(MyList.class);
    doNothing().when(myList).add(isA(Integer.class), isA(String.class));
    myList.add(0, "");
 
    verify(myList, times(1)).add(0, "");
}

However, doNothing() is Mockito’s default behavior for void methods.

然而,doNothing()是Mockito对void方法的默认行为。

This version of whenAddCalledVerified() accomplishes the same thing as the one above:

这个版本的whenAddCalledVerified()完成了与上面那个相同的事情。

@Test
public void whenAddCalledVerified() {
    MyList myList = mock(MyList.class);
    myList.add(0, "");
 
    verify(myList, times(1)).add(0, "");
}

DoThrow() generates an exception:

DoThrow()会产生一个异常。

@Test(expected = Exception.class)
public void givenNull_addThrows() {
    MyList myList = mock(MyList.class);
    doThrow().when(myList).add(isA(Integer.class), isNull());
 
    myList.add(0, null);
}

We’ll cover doAnswer() below.

我们将在下面讨论doAnswer()

3. Argument Capture

3.争论的捕捉

One reason to override the default behavior with doNothing() is to capture arguments.

doNothing()覆盖默认行为的一个原因是为了捕获参数。

In the example above, we used the verify() method to check the arguments passed to add().

在上面的例子中,我们使用verify()方法来检查传递给add()的参数。

However, we may need to capture the arguments and do something more with them.

然而,我们可能需要捕捉这些论点,并对其做更多的处理。

In these cases, we use doNothing() just as we did above, but with an ArgumentCaptor:

在这些情况下,我们像上面那样使用doNothing(),但要使用ArgumentCaptor

@Test
public void whenAddCalledValueCaptured() {
    MyList myList = mock(MyList.class);
    ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class);
    doNothing().when(myList).add(any(Integer.class), valueCapture.capture());
    myList.add(0, "captured");
 
    assertEquals("captured", valueCapture.getValue());
}

4. Answering a Call to Void

4.接听Void的电话

A method may perform more complex behavior than merely adding or setting value.

一个方法可以执行更复杂的行为,而不仅仅是添加或设置值。

For these situations, we can use Mockito’s Answer to add the behavior we need:

对于这些情况,我们可以使用Mockito的Answer来添加我们需要的行为。

@Test
public void whenAddCalledAnswered() {
    MyList myList = mock(MyList.class);
    doAnswer(invocation -> {
        Object arg0 = invocation.getArgument(0);
        Object arg1 = invocation.getArgument(1);
        
        assertEquals(3, arg0);
        assertEquals("answer me", arg1);
        return null;
    }).when(myList).add(any(Integer.class), any(String.class));
    myList.add(3, "answer me");
}

As explained in Mockito’s Java 8 Features, we use a lambda with Answer to define custom behavior for add().

正如Mockito的Java 8功能中所解释的,我们使用带有Answer的lambda来定义add()的自定义行为。

5. Partial Mocking

5.局部嘲弄

Partial mocks are an option too. Mockito’s doCallRealMethod() can be used for void methods:

部分模拟也是一种选择。Mockito的doCallRealMethod()可以用于void方法。

@Test
public void whenAddCalledRealMethodCalled() {
    MyList myList = mock(MyList.class);
    doCallRealMethod().when(myList).add(any(Integer.class), any(String.class));
    myList.add(1, "real");
 
    verify(myList, times(1)).add(1, "real");
}

This way, we can call the actual method and verify it at the same time.

这样一来,我们就可以在调用实际方法的同时验证它。

6. Conclusion

6.结论

In this brief article, we covered four different ways to approach void methods when testing with Mockito.

在这篇简短的文章中,我们介绍了在用Mockito进行测试时处理void方法的四种不同方式。

As always, the examples are available in this GitHub project.

一如既往,在这个GitHub项目中可以找到这些例子。