安卓单元测试Mockito的使用

本文详细介绍了Mockito在安卓单元测试中的使用,包括mock返回值、参数匹配器、验证调用次数、验证顺序等核心功能,以及如何使用@Mock注解、迭代器验证参数、创建间谍对象等高级特性。此外,还讨论了Mockito的BDD测试风格、自定义验证失败消息以及Java 8 Lambda Matcher Support等,帮助开发者深入理解和掌握Mockito在安卓单元测试中的实践。
摘要由CSDN通过智能技术生成

Android Mockito 使用目录

简单的例子

Mockito - mock返回值

Mockito - 参数匹配器

Mockito - 验证调用次数

Mockito - 验证顺序

Mockito - 保模与其他mock未发生相互影响

Mockito - 找出冗余的调用

Mockito - 使用@Mock注解

Mockito - 使用迭代器方式验证我们的参数

Mockito - spy (间谍)

Mockito - 重置

Mockito - BDD 测试

Mokito -  Verification with timeout

Mockito - 自定义验证失败消息

Mockito - when 的使用

Mockito - verify的使用

Mockito - 一些其他的API

doNothing

doReturn

inOrder

ignoreStubs

times

never

atLeastOnce

atLeast

atMost

calls

only

timeout

after


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.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值