• 0
  • 0
分享
  • 强大的Kotlin也能搞定,测试利器MockK你不能不知道
  • 大椿 2020-10-13 17:03:37 字数 2409 阅读 5054 收藏 0

为什么需要MockK

在MockK之前,已经有一大批测试库可以用于Mocking,其中有名的也有很多,比如Mockito, PowerMock,Jmockit等等,但是他们都有各自的缺陷,这些缺陷也和Kotlin的特性有关。

关键字

在 Kotlin 里面 when是关键字,Mockito 的when ,必须加上反引号才能使用:

`when`(xxxx).thenReturn(xxx)

如果看起来不舒服,也可以舍弃 Mockito 改用 mockito-kotlin。

在 mockito-kotlin中使用了whenever代替when,也有更简洁的写法,但是归根到底还是在使用Mockito的Api,所以功能上依然有局限性。

Mock Kotlin的类时报错

org.mockito.exceptions.base.MockitoException: Cannot mock/spy class com.joetsai.kotlinunittest.token.TokenRepositoryMockito cannot mock/spy because : — final class

这是因为Kotlin中类都是默认final类型,如果需要mock,则需要显示的加上open标识符,如果有100个类,则需要加100次,这也太麻烦了…

静态方法如何Mock

众所周知,Mockito是不支持静态方法的,如果想使用就需要使用PowerMock,但是PowerMock也有缺点。


  • 使用流程也比较繁琐。

  • Mockito与PowerMock是不同团队开发的,更新速度慢而且有兼容性问题。

Jmockit

完全与Kotlin不兼容…

MockK使用示例

普通使用

fun test() {    val mother = mockk<Mother>()    every { mother.giveMoney() } returns 30 // when().thenReturn() in Mockito    assertEquals(30, mother.giveMoney())}

mockkObject

object Son {    fun test5(): Int {        return 5    }}mockkObject(Son)every { Son.test5() } returns 10assertEquals(10, Son.test5())

mockkStatic

class Son {    Static int test5() {        return 5    }}   
@testfun test() {    mockkStatic(Son::class)    every { Son.test5() } returns 10    assertEquals(10, Son.test5())}

mock private method

class Son {    public int publicResult() {        return privateResult()    }    private int privateReuslt() {        return 5    }}   
@testfun test() {    val son = mockk<Son>()    every { son["privateResult"]() } returns 10    assertEquals(10, son.publicResult())}

Context Mock

在某些Android某些用户自定义的类中,需要Context才能初始化。

class Utils {    public static void initialize(Context context) {    instance = builder.build(context);    }    public static synchronized Utils getInstance() {        if (instance == null) {            throw new IllegalStateException("you must call initialize first");        }        return instance;    }}


有两种初始化方式:

直接mock context

val context = mockk<Context>()Utils.init(context)Utils.getInstance().xxxx()

直接mock Util

val mockApplicationContext = mockk<Context>()val utils = mockk<Utils.init>()mockkStatic(Utils.init::class)every { Utils.getInstance() } returns utilsevery { utils.test() } returns null......

遇到的一些小坑


  • 从介绍来看,在mockStatic时只能mock非final类,所以如果mock系统自带的System类会直接报错。

  • 在Android instrument test时,需要设备Android版本>=9。

  • 在最新版(1.10.2)的MockK中,需要Kotlin版本>=1.3.61

最后

因为当前项目是java和Kotlin混编的,所以举得例子中也有不少java的demo。


如果大家还有其他遇到的问题或者坑,欢迎留言。


作者:嘻嘻z

链接:https://juejin.im/post/6877824384694747143



  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          •   测试用例的设计方法  等价类  因材施教的例子:  原则上讲,老师都应该根据每个学生的学习情况制定相应符合的学习方案,但是实际上学生太多,老师管不过来,只能讲学生分为三六九等,优等生强调知识面的扩展和综合能力的提升,中等生强调夯实基础,查缺补漏,差等生强调优先掌握重点,暂时逃过难点.......  思路:输入的集合是无穷的,不能全部都覆盖到。  等价类:依据需求将输入划分为若干个等价类,从等价类中选出一个测试用例,如果这个测试用例测试通过,则认为所代表的整个等价类测试通过,这样就可以通过较少的测试用例达到尽量多的功能覆盖,解决了不能穷举测试的问题。  弊端:等价类只考虑输入域的分类,没有考...
            14 15 4713
            分享
          •   51testing软件测试圈“季度更文活动——万字更文”已经结束了,感谢各位的参与。  本次更文活动时间为2023年3月1日--2023年4月16日!  获奖情况和评审情况如下表所示:作者投稿字数6分及以上的文章数活动奖品九哥91542篇公牛魔方插座米果橙柠149140篇小米加湿器FunTeste742958篇小米加湿器*额外奖励100元京东卡优秀文章一览:· 卷完职场卷AI,测试真的会被ChatGPT代替吗?· 金三银四想跳槽?这篇测试人分龄跳槽指南请收好· 应对自动化测试9大挑战· 敏捷 ? DevOps ?· 国际化和本地化测试·&n...
            1 1 6511
            分享
          • 由于安全意识不到位及系统配置不够专业,网络服务器和客户端很容易成为网络攻击的目标。为了保证系统和数据的安全,管理员需要及时发现服务器、客户端所存在的安全漏洞,并进行迅速修复。网络安全扫描工具TCP端口和UDP端口,就像计算机的多个不同的门,通过任何一个门可到达系统。换句话说,无论攻击方法多么高明,均必须使用TCP或UDP端口。因此,将系统中的危险端口,或者非必要端口关闭,可以再一定程度上保证计算机的安全。以下是一些常见的网络安全扫描工具:1、 TCP和UDP连接测试:netstat2、 网络邻居信息探测工具:nbtstat3、网络主机扫描:HostScan4、漏洞检测:X-...
            12 12 846
            分享
          •   综合汽车产经网、东风日产官方今日消息,东风日产副总经理周峰首次在在访谈中提及东风日产在新能源领域布局情况,以及合资品牌新能源“何去何从”的问题。  周峰称,在过去的若干年,东风日产一直在产品、技术领域里面是领先半步,内部也在反思,对于整个中国的新能源市场发展预判、预见事实上是有偏差的,在整个战略维度的背后也有一些“犹豫”,这个“犹豫”让东风日产丧失了最好的窗口期。  周峰还对东风日产与华为的合作进行简要描述:东风日产和华为已经签订战略合作协议,联合智能座舱的打造,应该是合资公司里的首家,相信在不远的时间里,能跟华为一起向客户展开相应完整的解决方案行动计划。  据此前报道,东风日产在今年 6...
            0 0 127
            分享
          •   一、缓存测试  缓存系统的使用,在一定程度上,极大的提升了应用程序的性能和效率,在秒杀系统的建设上,缓存系统出力不小,特别是数据查询方面,数据的快速返回广受好评。但同时,它也带来了一些问题,测试过程中,如果没有及时关注到缓存系统,整个测试环节是有遗漏的。缓存系统没有经过严格的测试,容易产生一个严重的问题,就是数据的一致性问题。如果没有对缓存系统进行测试,并且后端系统对数据的一致性要求很高,那么就不能使用缓存。  缓存的主要作用:是将业务系统的数据处理结果,暂时在内存中保存,并且等待下次访问的时候,立马从内存中取出。在日常开发场景中,因为服务器的性能或者自身业务对数据处理非常耗时的时候,当发...
            14 15 1936
            分享
      • 51testing软件测试圈微信