Mockito-步骤介绍(二)
Mockito-方法介绍(二)
前言
前篇《Mockito-方法介绍(一)》刚介绍完前六项关于Mockito方法的使用,现在我们继续介绍后七项,详细可参考http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mockito.html官网网站。
正题
7.Making sure interaction(s) never happened on mock-确保Mock对象从未调用过
@Test public void testMockito7() { List mockOne = mock(List.class); List mockTwo = mock(List.class); List mockThree = mock(List.class); // mockOne和mockTwo都有调用,mockThree没有 mockOne.add("one"); mockTwo.add("two"); // 普通的调用验证 verify(mockOne).add("one"); // add.("two")从未被调用过 verify(mockOne, never()).add("two"); // 下面的验证会失败,因为mockOne和mockTwo都有调用 verifyZeroInteractions(mockOne, mockTwo); // 下面验证会成功,因为mockThree没有过调用 verifyZeroInteractions(mockOne, mockThree); }
8.Finding redundant invocations-寻找冗余的调用
verifyNoMoreInteractions() is not recommended to use in every test method. verifyNoMoreInteractions() is a handy assertion from the interaction testing toolkit. Use it only
when it's relevant. Abusing it leads to overspecified, less maintainable tests.——来自官网
不要滥用verifyNoMoreInteractions()方法,只有当需要用的时候再用,滥用会导致不好维护。
@Test public void testMockito8() { LinkedList mockedList1 = mock(LinkedList.class); LinkedList mockedList2 = mock(LinkedList.class); // using mocks mockedList1.add("one"); mockedList1.add("two"); verify(mockedList1).add("one"); // 下面验证会失败 verifyNoMoreInteractions(mockedList1); // 下面验证会成功 verifyNoMoreInteractions(mockedList2); }
9.Shorthand for mocks creation - 快速创建mock对象使用注解@Mock
Important! This needs to be somewhere in the base class or a test runner:MockitoAnnotations.initMocks(testClass);——来自官网
注解是创建对象的一种快速的方式,在这里我们要注意如果要使用注解则需要测试类里面初始化注解:MockitoAnnotations.initMocks(testClass);
public class ArticleManagerTest extends SampleBaseTestCase { @Mock private ArticleCalculator calculator; @Mock private ArticleDatabase database; @Mock private UserProvider userProvider; private ArticleManager manager; @Before public void setup() { manager = new ArticleManager(userProvider, database, calculator); } } public class SampleBaseTestCase { @Before public void initMocks() { MockitoAnnotations.initMocks(this); } }
10.Stubbing consecutive calls (iterator-style stubbing)-迭代调用
Sometimes we need to stub with different return value/exception for the same method call. Typical use case could be mocking iterators. Original version of Mockito did not have
this feature to promote simple mocking. ——来自官网
有时我们可以需要调用同一个方法多次,每次需要有不同的返回值(例如迭代),这时我们需要对同一个方法设置不同的返回值/期望值,这个根据调用次数来返回不同的值的特性是Mockito后来添加的。
这个其实跟上一篇的第一点提到的多次覆盖期望值一样。
@Test public void testMockito10() { LinkedList mock = mock(LinkedList.class); when(mock.get(0)).thenReturn("first").thenReturn("second").thenReturn("third"); // 第一次调用,输出"first" System.out.println(mock.get(0)); // 第二次调用,输出"second" System.out.println(mock.get(0)); // 第三次及以后调用,都输出"third" System.out.println(mock.get(0)); }
11. Stubbing with callbacks-回调函数作为期望值
Yet another controversial feature which was not included in Mockito originally. We recommend using simple stubbing with toReturn() or toThrow() only. Those two should be just
enough to test/test-drive any clean & simple code.——来自官网
该特性也是最开始Mockito里面没有的,比较有争议性,建议使用简单的toReturn()和toThrow()来设置期望值即可。
@Test public void testMockito11(){ LinkedList mock = mock(LinkedList.class); when(mock.get(0)).thenAnswer(new Answer() { public Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); Object mock = invocation.getMock(); return "called with arguments: " + args.length; } }); //Following prints "called with arguments: 1" System.out.println(mock.get(0)); }
12.doThrow()|doAnswer()|doNothing()|doReturn() family of methods for stubbing voids (mostly)-void方法常用的stubbing
这个在前篇的第五点里面提到过,原来有个stubVoid方法专门用于void方法调用的。现在这几个方法替代了stubVoid()方法。
@Test public void testMockito12() { LinkedList mockedList = mock(LinkedList.class); doThrow(new RuntimeException()).when(mockedList).clear(); // 下面调用会抛异常 mockedList.clear(); }
13.Spying on real objects-监控一个真实的对象
Mock对象的方法是不会被真实调用的,Spy则不同,它是真实的去调用那个方法,但是你又可以在需要时候对某些方法设置期望的返回值,如果没有设置的话则会真实去调用那个方法。
如果我们有个Service类,一般我们会将该Service设置为Spy对象,而该Service调用的dao则设置为mock对象。
@Test public void testMockito13() { List list = new LinkedList(); List spy = spy(list); // Spy对象也可以设置期望值 when(spy.size()).thenReturn(100); // 使用spy对象调用真实的方法 spy.add("one"); spy.add("two"); // 输出"one" System.out.println(spy.get(0)); // 由于我们对size设置了期望值,所以下面会输出期望值100 System.out.println(spy.size()); // 验证方法的调用 verify(spy).add("one"); verify(spy).add("two"); }
小结:
Mockito的方法到这里基本介绍结束。这些例子可以在这里下载。后续会介绍在工作中我是如果应用Mockito的。