mockito详解

mockito详解

介绍

  • Mockito库允许模拟创建, 验证和存根。
  • mock对象就是在调试期间用来作为真实对象的替代品。
  • mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。

特性

  • 先来一个小的例子
 //先导入静态方法,让代码看上去更加简洁
 import static org.mockito.Mockito.*;

 //创建mock对象
 List mockedList = mock(List.class);

 //使用mock对象
 mockedList.add("one");
 mockedList.clear();

 //验证
 verify(mockedList).add("one");
 verify(mockedList).clear();

mock对象一旦被创建,会记住所有的验证,并在你感兴趣的时候提供可选的校验

  • 来谈谈stubbing吧

 //You can mock concrete classes, not just interfaces
 LinkedList mockedList = mock(LinkedList.class);

 //stubbing
 when(mockedList.get(0)).thenReturn("first");
 when(mockedList.get(1)).thenThrow(new RuntimeException());

 //following prints "first"
 System.out.println(mockedList.get(0));

 //following throws runtime exception
 System.out.println(mockedList.get(1));

 //following prints "null" because get(999) was not stubbed
 System.out.println(mockedList.get(999));

 //Although it is possible to verify a stubbed invocation, usually it's just redundant
 //If your code cares what get(0) returns, then something else breaks (often even before verify() gets executed).
 //If your code doesn't care what get(0) returns, then it should not be stubbed. Not convinced? See here.
 verify(mockedList).get(0);
  • 默认情况下所有的方法都会有一个返回值,一个mock将返回null,空的集合,包装类型。例如int则返回0,boolean则返回false
  • stubbing 可以被重写:例如常见的stub可以去固定设置,但测试方法可以覆盖它。请注意,overridding存根是一个潜在的代码味道,指太多的存根
  • 一旦创建了stubbing,不论调用多少次测试方法都会返回一个值
    //重复stub两次,则以第二次为准。如下将返回”second”:
    when(mockedList.get(0)).thenReturn(“first”).thenReturn(“second”);
    但是,如果实际调用的次数超过了stub过的次数,则会一直返回最后一次stub的值。
  • 参数匹配

 //stubbing using built-in anyInt() argument matcher
 when(mockedList.get(anyInt())).thenReturn("element");

 //stubbing using custom matcher (let's say isValid() returns your own matcher implementation):
 when(mockedList.contains(argThat(isValid()))).thenReturn("element");

 //following prints "element"
 System.out.println(mockedList.get(999));

 //you can also verify using an argument matcher
 verify(mockedList).get(anyInt());

 //argument matchers can also be written as Java 8 Lambdas
 verify(mockedList).add(someString -> someString.length() > 5);
  • 如果想要传入某种类型的值都返回一种结果,需要怎么做呢?
  • stubbing 使用了内置的anyint() matcher.除了anyint()还有其他类型的matcher,但是有个延迟是,如果调用方法需要传入多个参数,其中一个使用了参数matcher,那么所有的参数都需要使用matcher
  • 有时候我们的许多类型都不是内建的一些类型,我们需要自己写一个类或者特殊对象,这个时候就需要自己定义matcher了
  • 调用次数的校验

 //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("five times");
 verify(mockedList, atMost(5)).add("three times");
  • 调用方法时抛出异常

doThrow(new RuntimeException()).when(mockedList).clear();

后面还会再介绍几个类似的方法,例如doReturn()。

  • 验证方法调用顺序

//下面的代码验证firstMock先被调用,secondMock后被调用。

inOrder.verify(firstMock).add(“was called first”);

inOrder.verify(secondMock).add(“was called second”);

先写到这里吧,等下班了再整理下一篇

你可能感兴趣的:(测试)