分享

单元测试-如何去mock对象

 520jefferson 2020-10-24

作者丨Coder技术栈

来源丨匠心Java(ID:code-the-world)

概念

Mock的概念,其实很简单:所谓的mock就是创建一个类的虚假的对象,在测试环境中,用来替换掉真实的对象,以达到两大目的:

  • 验证这个对象的某些方法的调用情况,调用了多少次,参数是什么等等

  • 指定这个对象的某些方法的行为,返回特定的值,或者是执行特定的动作

上述两大目的应该好好理解一下,理解了目的也就大致知道了何时使用mock

使用场景

  • 被测试对象依赖的对象构造复杂

比如:class A 依赖 class B、class B 依赖 class C和class D、class C 依赖 ...、class D 依赖 ...此处我们想测试classA,在没有mock的情况下就要去根据要求去构造classBCD等对象,耗时耗力。在mock的情况下,我们可以直接mockclassBCD并通过设计其行为来实现测试classA的目的,因为我们只是想测试class A的行为是否符合预期,我们并不需要测试依赖对象。

  • 被测试单元所依赖的模块还没有开发完成,而被测试对象需要需要依赖模块的返回值进行测试。也就是测试单元依赖了无法获取的下游数据

比如:service中方法的测试需要dao中的访问数据库操作并获取其返回值,但是我们还没有开发完成对应的dao方法,我们就可以mock一个dao层的对象,将其行为设置为:当调用其中的某个方法时返回一个设定的值。这样我们对service的测试就可以不必受dao层的开发速度影响。也符合只对service方法逻辑进行测试。

原则

  • 不需要对所有的单元测试都将对象进行mock,只对上述使用场景介绍的相关场景使用mock。

  • 在分层测试中,高层的测试设计可以基于以下假设:底层的测试已保证底层对象的质量,高层无需关心低层对象的内部逻辑质量。这种情况下高层可以对低层对象进行mock。

常用框架

  • EasyMock :早期比较流行的mock框架,它提供对接口的模拟,能够通过录制、回放、检查三步来完成大体的测试过程,可以验证方法的调用种类、次数、顺序,可以令 Mock 对象返回指定的值或抛出指定异常

  • Mockito:EasyMock之后流行的mock工具。相对EasyMock学习成本低,而且具有非常简洁的API,测试代码的可读性很高。

  • PowerMock:这个工具是在EasyMock和Mockito上扩展出来的,目的是为了解决EasyMock和Mockito不能解决的问题,比如对static, final, private方法均不能mock。

其实测试架构设计良好的代码,一般并不需要这些功能,但如果是在已有项目上增加单元测试,老代码有问题且不能改时,就不得不使用这些功能了。PowerMock 在扩展功能时完全采用和被扩展的框架相同的 API, 熟悉 PowerMock 所支持的模拟框架的开发者会发现 PowerMock 非常容易上手。PowerMock 的目的就是在当前已经被大家所熟悉的接口上通过添加极少的方法和注释来实现额外的功能。目前PowerMock 仅扩展了 EasyMock 和 mockito,需要和EasyMock或Mockito配合一起使用。

  • Jmockit:JMockit 是一个轻量级的mock框架是用以帮助开发人员编写测试程序的一组工具和API,该项目完全基于 Java 5 SE 的 java.lang.instrument 包开发,内部使用 ASM 库来修改Java的Bytecode。

Jmockit功能和PowerMock类似,某些功能甚至更为强大,但个人感觉其代码的可读性并不强。

mock框架有好多,我们在选用mock框架时可以根据使用环境使用相对的mock框架,不过在正常情况下,个人感觉mockito还是不错的:代码可读性强,易于上手,功能绝大数项目的单元测试都够用,不需要依赖其他组件。这或许也是mockito这么流行的原因吧。

refer:博客 博客

程序员专栏

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多