Android Mockito 使用目录
Mokito - Verification with timeout
Mockito - Android支持
在Mockito 2.6.1版中,提供了“本机” Android支持。要启用Android支持,请将`mockito-android`库作为依赖项添加到我们的项目中。该工件已发布到同一Mockito组织,并且可以如下导入Android:
repositories {
jcenter()
}
dependencies {
testImplementation "org.mockito:mockito-core:+"
androidTestImplementation "org.mockito:mockito-android:+"
}
我们可以通过在“ testImplementation”范围内使用“ mockito-core”库,继续在常规VM上运行相同的单元测试,如上所示。请注意,由于Android VM中的限制,我们不能在Android上使用Mockito,但是如果我们想要使用的话那么需要倒入“mockito-android”。
简单的例子
//Let's import Mockito statically so that the code looks clearer
import static org.mockito.Mockito.*;//mock creation
List mockedList = mock(List.class);
//using mock object
mockedList.add("one");
mockedList.clear();
//verification List add() method called and param is "one"
verify(mockedList).add("one");
//verification List clear() method called
verify(mockedList).clear();
一旦创建,模拟程序将会记住所有的交互。然后我们就可以有选择的验证我们感兴趣的任何事情。
Mockito - mock返回值
//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));
//虽然可以验证存根调用,但通常只是多余的
//如果我们的代码关心get(0)返回的内容,则其他内容将中断(甚至在执行verify()之前)。
//如果我们的代码不关心get(0)返回的内容,则不应将其存根。不服气吗?看这里。
verify(mockedList).get(0);
-
默认情况下,对于所有返回值的方法,Mockito将根据需要返回null,原始/原始包装器值或空集合。例如,对于int / Integer为0,对于boolean / Boolean为false。
-
存根可以被覆盖:例如,通用存根可以正常设置,但是测试方法可以覆盖它。请注意,过多的存根使代码过于难看和不优雅,这表明存在过多的存根。
-
一旦存根,该方法将始终返回存根值,而不管其被调用了多少次。
-
最后一次存根更为重要-当我们多次对具有相同参数的相同方法进行存根时。换句话说:存根的顺序很重要,但很少有意义,例如,存根完全相同的方法调用时或有时使用参数匹配器时,等等。
Mockito - 参数匹配器
Mockito通过使用一种 equals() 方法来验证自然Java风格的参数值。有时,当需要额外的灵活性时,我们可以使用参数匹配器:
//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(argThat(someString -> someString.length() > 5));
参数匹配器允许灵活的验证或存根。 查看更多内置匹配器以及自定义参数匹配器参考此文档有关仅自定义参数匹配器的信息,请查看javadoc中的ArgumentMatcher类。使用复杂的参数匹配是合理的。将equals()与 anyX()匹配器配合使用的自然匹配样式倾向于提供简洁的测试。有时最好重构代码以允许equals()匹配,甚至实现equals()方法来帮助进行测试。
关于参数匹配器的注意事项
如果使用参数匹配器,则必须由匹配器提供所有参数。
以下示例显示了验证,但对存根也是如此:
verify(mock).someMethod(anyInt(), anyString(), eq("third argument"));
//这是个正确的例子因为eq()是一个Matcher
verify(mock).someMethod(anyInt(), anyString(), "third argument");
//这是个错误的例子会抛出一个异常因为 "third argument" 不是一个 Matcher 类
诸如anyObject(),eq()之类的匹配器方法不会返回匹配器。在内部,它们在堆栈上记录一个匹配器,并返回一个虚拟值(通常为null)。此实现归因于Java编译器施加的静态类型安全性。结果是我们不能在经过验证/存根的方法之外使用anyObject()和eq()方法。
Mockito - 验证调用次数
//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");
默认为times(1)。因此,可以显式地省略使用times(1)。
Mockito - 验证顺序
// A. Single mock whose methods must be invoked in a particular order
List singleMock = mock(List.