1、什么是mock测试,什么是mock对象?html
先来看看下面这个示例:java
从上图能够看出若是咱们要对A进行测试,那么就要先把整个依赖树构建出来,也就是BCDE的实例。app
一种替代方案就是使用mocks框架
从图中能够清晰的看出maven
mock对象就是在调试期间用来做为真实对象的替代品。svn
mock测试就是在测试过程当中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。测试
知道什么是mock测试后,那么咱们就来认识一下mock框架---Mockitogoogle
2、什么是Mockitospa
除了有一个好记的名字外,Mockito尝试用不同的方法作mocking测试,是简单轻量级可以替代EasyMock的框架。使用简单,测试代码可读性高,丰富的文档包含在javadoc中,直接在IDE中可查看文档,实例,说明。更多信息:http://code.google.com/p/mockito/调试
3、Stub和Mock
相同点:Stub和Mock对象都是用来模拟外部依赖,使咱们能控制。
不一样点:而stub彻底是模拟一个外部依赖,用来提供测试时所须要的测试数据。而mock对象用来判断测试是否能经过,也就是用来验证测试中依赖对象间的交互可否达到预期。在mocking框架中mock对象能够同时做为stub和mock对象使用,二者并无严格区别。 更多信息:http://martinfowler.com/articles/mocksArentStubs.html
4、mockito入门实例
Maven依赖:(没用maven管理的能够下载相关jar包导入classpath)
<dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>1.9.5</version> <scope>test</scope> </dependency>
import static org.mockito.Mockito.*; import java.util.List; import org.junit.Assert; import org.junit.Test; /** * * @author lzjun * @version 0.1 * @date 2012-5-5 * {@link http://weibo.com/u/1697702241} * */ public class SimpleTest { @Test public void simpleTest(){ //建立mock对象,参数能够是类,也能够是接口 List<String> list = mock(List.class); //设置方法的预期返回值 when(list.get(0)).thenReturn("helloworld"); String result = list.get(0); //验证方法调用(是否调用了get(0)) verify(list).get(0); //junit测试 Assert.assertEquals("helloworld", result); } }
好了,五分钟差很少了,还想继续了解那就能够往下面看
建立mock对象不能对final,Anonymous ,primitive类进行mock。
可对方法设定返回异常
when(list.get(1)).thenThrow(new RuntimeException("test excpetion"));
stubbing另外一种语法(设置预期值的方法),可读性不如前者
doReturn("secondhello").when(list).get(1);
没有返回值的void方法与其设定(支持迭代风格,第一次调用donothing,第二次dothrow抛出runtime异常)
doNothing().doThrow(new RuntimeException("void exception")).when(list).clear(); list.clear(); list.clear(); verify(list,times(2)).clear()
5、参数匹配器(Argument Matcher)
Matchers类内加你有不少参数匹配器 anyInt、anyString、anyMap.....Mockito类继承于Matchers,Stubbing时使用内建参数匹配器,下例:
@Test public void argumentMatcherTest(){ List<String> list = mock(List.class); when(list.get(anyInt())).thenReturn("hello","world"); String result = list.get(0)+list.get(1); verify(list,times(2)).get(anyInt()); Assert.assertEquals("helloworld", result); }
须要注意的是:若是使用参数匹配器,那么全部的参数都要使用参数匹配器,无论是stubbing仍是verify的时候都同样。
@Test public void argumentMatcherTest2(){ Map<Integer,String> map = mock(Map.class); when(map.put(anyInt(),anyString())).thenReturn("hello");//anyString()替换成"hello"就会报错 map.put(1, "world"); verify(map).put(eq(1), eq("world")); //eq("world")替换成"world"也会报错 }
6、方法调用的验证(具体的调用次数、至少一次,一次也没有)
@Test public void verifyInvocate(){ List<String> mockedList = mock(List.class); //using mock mockedList.add("once"); mockedList.add("twice"); mockedList.add("twice"); mockedList.add("three times"); mockedList.add("three times"); mockedList.add("three times"); /** * 基本的验证方法 * verify方法验证mock对象是否有没有调用mockedList.add("once")方法 * 不关心其是否有返回值,若是没有调用测试失败。 */ verify(mockedList).add("once"); verify(mockedList, times(1)).add("once");//默认调用一次,times(1)能够省略 verify(mockedList, times(2)).add("twice"); verify(mockedList, times(3)).add("three times"); //never()等同于time(0),一次也没有调用 verify(mockedList, times(0)).add("never happened"); //atLeastOnece/atLeast()/atMost() verify(mockedList, atLeastOnce()).add("three times"); verify(mockedList, atLeast(2)).add("twice"); verify(mockedList, atMost(5)).add("three times"); }
一次写不完,慢慢分析。。。
参考:
http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mockito.html
http://www.sizovpoint.com/2009/03/java-mock-frameworks-comparison.html