前言
前篇《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的。