Mockito Framework用法简介

编程过程可以抽象为expect-run-verify,而在Java中我们常用单元测试来保证程序运行结果符合我们的预期。

Mockito可以实现:

  • 在得到程序输出结果后,验证结果是否符合预期;
  • 在其依赖方法还没有编写完成时,mock接口的执行结果。

mock

  • 通过when(...).then(...)指定具体行为动作的mock结果;
  • 可通过如下方式自定义响应:
 when(mock.someMethod(anyString())).thenAnswer(
     new Answer() {
         public Object answer(InvocationOnMock invocation) {
             Object[] args = invocation.getArguments();
             Object mock = invocation.getMock();
             return "called with arguments: " + Arrays.toString(args);
         }
 });

 //Following prints "called with arguments: [foo]"
 System.out.println(mock.someMethod("foo"));
import static org.mockito.Mockito.*;

// 通过mock方法创建一个mock类,该实例的所有调用返回的都是mock值
List mockedList = mock(List.class);

// 使用mock实例,不会抛出任何非检查型异常
mockedList.add("one");
mockedList.clear();

// 验证某方法是否执行过
verify(mockedList).add("one");
verify(mockedList).clear();

//定义一个stub存根,mock方法执行返回结果
when(mockedList.get(0)).thenReturn("first");

// 命中stub,符合上面定义的mock条件,返回mock结果
System.out.println(mockedList.get(0));

// 因为get(999)未命中stub,故返回null
System.out.println(mockedList.get(999));

测试输出结果如下:

mock测试结果

@mock

public class ArticleManagerTest extends SampleBaseTestCase {

       @Mock private ArticleCalculator calculator;
       @Mock(name = "database") private ArticleDatabase dbMock;
       @Mock(answer = RETURNS_MOCKS) private UserProvider userProvider;
       @Mock(extraInterfaces = {Queue.class, Observer.class}) private  articleMonitor;

       private ArticleManager manager;

       @Before public void setup() {
           manager = new ArticleManager(userProvider, database, calculator, articleMonitor);
       }
   }

   public class SampleBaseTestCase {

       @Before public void initMocks() {
            //MockitoAnnotations.initMocks(this)必须在test执行前调用
           MockitoAnnotations.initMocks(this);
       }
   }

spy

  • mock代理部分指定的方法,其余方法都执行真实的方法动作。
List list = new LinkedList();
List spy = spy(list);

//可以选择性stub部分方法,其余未被代理的方法会真实执行
when(spy.size()).thenReturn(100);

//真实调用执行
spy.add("one");
spy.add("two");

//打印第一个元素
System.out.println(spy.get(0));

//size() 方法被mock代理了,返回设定值:100
System.out.println(spy.size());

//验证
verify(spy).add("one");
verify(spy).add("two");

测试输出结果如下:


spy测试结果

@spy

public class Test{
   //Instance for spying is created by calling constructor explicitly:
   @Spy Foo spyOnFoo = new Foo("argument");
   //Instance for spying is created by mockito via reflection (only default constructors supported):
   @Spy Bar spyOnBar;
   @Before
   public void init(){
      MockitoAnnotations.initMocks(this);
   }
   ...
}

/****************等同于*********/
Foo spyOnFoo = Mockito.spy(new Foo("argument"));
Bar spyOnBar = Mockito.spy(new Bar());

verify

  • 验证执行方法是否被调用执行指定的次数
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");

 //following two verifications work exactly the same - times(1) is used by default
 verify(mockedList).add("once");
 verify(mockedList, times(1)).add("once");

 //exact number of invocations verification
 verify(mockedList, times(2)).add("twice");
 verify(mockedList, times(3)).add("three times");

 //verification using never(). never() is an alias to times(0)
 verify(mockedList, never()).add("never happened");

 //verification using atLeast()/atMost()
 verify(mockedList, atLeastOnce()).add("three times");
 verify(mockedList, atLeast(2)).add("three times");
 verify(mockedList, atMost(5)).add("three times");

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 几点说明:代码中的 //<== 表示跟上面的相比,这是新增的,或者是修改的代码,不知道怎么样在代码块里面再强调几行...
    邹小创阅读 14,765评论 15 41
  • 在博客Android单元测试之JUnit4中,我们简单地介绍了:什么是单元测试,为什么要用单元测试,并展示了一个简...
    水木飞雪阅读 13,185评论 4 18
  • 什么是 Mock mock 的中文译为: 仿制的,模拟的,虚假的。对于测试框架来说,即构造出一个模拟/虚假的对象,...
    Whyn阅读 9,833评论 0 3
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,347评论 19 139
  • 什么是单元测试 在计算机编程中,单元测试(Unit Testing)又称为模块测试, 是针对程序模块(软件设计的最...
    HelloCsl阅读 13,745评论 1 46