1、概述
本文的主要内容是用Mockito来mock无返回值的方法。
下面是为测试准备的类
1. public class MyList extends AbstractList<String> { 2. 3. @Override 4. public void add(int index, String element) { 5. // no-op 6. } 7. }
2、简单mock和验证
可以用 Mockito的doNothing()、doThrow()和doAnswer() 来对无返回值的函数进行Mock和验证。
1. @Test 2. public void whenAddCalledVerfied() { 3. MyList myList = mock(MyList.class); 4. doNothing().when(myList).add(isA(Integer.class), isA(String.class)); 5. myList.add(0, ""); 6. 7. verify(myList, times(1)).add(0, ""); 8. }
然而在Mockito中doNothing()是对无返回值的方法mock的默认行为。
下面代码和上面的等价
1. @Test 2. public void whenAddCalledVerfied() { 3. MyList myList = mock(MyList.class); 4. myList(0, ""); 5. 6. verify(myList, times(1)).add(0, ""); 7. }
DoThrow() 则会产生异常
1. @Test(expected = Exception.class) 2. public void givenNull_AddThrows() { 3. MyList myList = mock(MyList.class); 4. doThrow().when(myList).add(isA(Integer.class), isNull()); 5. 6. myList.add(0, null); 7. }
下面将介绍doAnswer()
3、参数获取
重写doNothing() 这个默认行为的一个重要原因是获取参数。
正如第二部分的例子,通过verify() 验证了参数传给了add()函数。
那么,如果我们需要获取参数来干点其他事情该怎么做呢?
依然还需要用doNothing() ,只不过要用到ArgumentCaptor。
1. @Test 2. public void whenAddCalledValueCaptured() { 3. MyList myList = mock(MyList.class); 4. ArgumentCaptor valueCapture = ArgumentCaptor.forClass(String.class); 5. doNothing().when(myList).add(any(Integer.class), valueCapture.capture()); 6. myList.add(0, "captured"); 7. 8. assertEquals("captured", valueCapture.getValue()); 9. }
4、对void返回类型的方法构造answer
方法可能不仅仅只是添加一个值那么简单。这时就需要用到 Answer 类来添加我们需要的其他行为。
1. @Test 2. public void whenAddCalledAnswered() { 3. MyList myList = mock(MyList.class); 4. doAnswer((Answer) invocation -> { 5. Object arg0 = invocation.getArgument(0); 6. Object arg1 = invocation.getArgument(1); 7. 8. assertEquals(3, arg0); 9. assertEquals("answer me", arg1); 10. return null; 11. }).when(myList).add(any(Integer.class), any(String.class)); 12. myList.add(3, "answer me");
这里也支持使用lambda表达式。
5、部分mock
Mockito的doCallRealMethod() 方法可以用在void函数上。
1. @Test 2. public void whenAddCalledRealMethodCalled() { 3. MyList myList = mock(MyList.class); 4. doCallRealMethod().when(myList).add(any(Integer.class), any(String.class)); 5. myList.add(1, "real"); 6. 7. verify(myList, times(1)).add(1, "real"); 8. }
这个函数允许我们调用原始对象的实际方法同时也允许我们去调用验证。
6、结论
本文介绍了Mockito中四种对void返回值的函数进行Mock的方法。
英文原文:https://www.baeldung.com/mockito-void-methods
源代码:https://github.com/eugenp/tutorials/tree/master/testing-modules/mockito