Mockito:一个强大的开源Java模拟测试框架

一、Mockito简介

mockito

先来看看下面这个示例:

mockito_demo1

从上图可以看出如果我们要对A进行测试,那么就要先把整个依赖树构建出来,也就是BCDE的实例。

一种替代方案就是使用mock:

mockito_demo2

从图中可以清晰的看出,mock对象就是在调试期间用来作为真实对象的替代品。mock测试就是在测试过程中,对那些不容易构建的对象用一个虚拟对象来代替测试的方法就叫mock测试。

知道什么是mock测试后,那么我们就来认识一下mock框架——Mockito。

Mockito是一个强大的基于MIT协议的用于Java开发的模拟测试框架。其他还有 EasyMock,JMock,MockCreator,Mockrunner,MockMaker 及 PowerMock。

Mockito区别于其他模拟框架的地方主要是允许开发者在没有建立“预期”时验证被测系统的行为。对于mock对象的一个评价是测试系统的测试代码是一个高耦合的,由于 Mockito试图通过移除“期望规范”去除expect-run-verify(期望验证模式)的模式,因此在耦合度上有所降低。这样的结果是简化了测试代码,使他更易读和修改了。

二、Mock关键点

在谈到Mock(模拟)时,你只需关心三样东西:设置测试数据,设定预期结果,验证结果。一些单元测试方案根本就不涉及这些,有的只涉及设置测试数据,有的只涉及设定预期结果和验证。

Stubbing 

Stubbing(桩)就是告诉fake当与之交互时执行何种行为过程。通常它可以用来提供那些测试所需的公共属性(像getters和setters)和公共方法。

当谈到stubbing方法,通常你有一系列的选择。或许你希望返回一个特殊的值,抛出一个错误或者触发一个事件,此外,你可能希望指出方法被调用时的不同行为(即通过传递匹配的类型或者参数给方法)。

这咋一听起来工作量很大,但通常并非这样。许多mocking框架的一个重要功能就是你不需要提供stub 的实体方法,也不用在执行测试期间stub那些未被调用的方法或者未使用的属性。

设置预期

Fake的一个关键的特性就是当你用它进行模拟测试时你能够告诉它你预期的结果。例如,你可以要求一个特定的函数被准确的调用3次,或不被调用,或调用至少两次但不超过5次,或者需要满足特定类型的参数、特定值和以上任意的组合的调用。可能性是无穷的。

通过设定预期结果告诉fake你期望发生的事情。因为它是一个模拟测试,所以实际上什么也没发生。但是,对于被测试的类来说,它并无法区分这种情况。所以fake能够调用函数并让它做它该做的。

值得注意的是,大多数模拟框架除了可以创建接口的模拟测试外,还可以创建公有类的模拟测试。

验证预期结果

设置预期和验证预期是同时进行的。设置预期在调用测试类的函数之前完成,验证预期则在它之后。所以,首先你设定好预期结果,然后去验证你的预期结果是否正确。

在一个单元测试中,如果你设定的预期没有得到满足,那么这个单元测试就是失败了。例如,你设置预期结果是 ILoginService.login函数必须用特定的用户名和密码被调用一次,但是在测试中它并没有被调用,这个fake没被验证,所以测试失败。

三、Mock的好处

提前创建测试;TDD(测试驱动开发)

这是个最大的好处吧。如果你创建了一个Mock那么你就可以在service接口创建之前写Service Tests了,这样你就能在开发过程中把测试添加到你的自动化测试环境中了。换句话说,模拟使你能够使用测试驱动开发。

团队可以并行工作

这类似于上面的那点;为不存在的代码创建测试。但前面讲的是开发人员编写测试程序,这里说的是测试团队来创建。当还没有任何东西要测的时候测试团队如何来创建测试呢?模拟并针对模拟测试!这意味着当service借口需要测试时,实际上QA团队已经有了一套完整的测试组件;没有出现一个团队等待另一个团队完成的情况。这使得模拟的效益型尤为突出了。

你可以创建一个验证或者演示程序

由于Mocks非常高效,Mocks可以用来创建一个概念证明,作为一个示意图,或者作为一个你正考虑构建项目的演示程序。这为你决定项目接下来是否要进行提供了有力的基础,但最重要的还是提供了实际的设计决策。

为无法访问的资源编写测试

这个好处不属于实际效益的一种,而是作为一个必要时的“救生圈”。有没有遇到这样的情况?当你想要测试一个service接口,但service需要经过防火墙访问,防火墙不能为你打开或者你需要认证才能访问。遇到这样情况时,你可以在你能访问的地方使用MockService替代,这就是一个“救生圈”功能。

Mock 可以分发给用户

在有些情况下,某种原因你需要允许一些外部来源访问你的测试系统,像合作伙伴或者客户。这些原因导致别人也可以访问你的敏感信息,而你或许只是想允许访问部分测试环境。在这种情况下,如何向合作伙伴或者客户提供一个测试系统来开发或者做测试呢?最简单的就是提供一个mock,无论是来自于你的网络或者客户的网络。soapUI mock非常容易配置,他可以运行在soapUI或者作为一个war包发布到你的java服务器里面。

隔离系统

有时,你希望在没有系统其他部分的影响下测试系统单独的一部分。由于其他系统部分会给测试数据造成干扰,影响根据数据收集得到的测试结论。使用mock你可以移除掉除了需要测试部分的系统依赖的模拟。当隔离这些mocks后,mocks就变得非常简单可靠,快速可预见。这为你提供了一个移除了随机行为,有重复模式并且可以监控特殊系统的测试环境。

开发资源

官方网站:http://mockito.org/
开源地址:https://github.com/mockito/mockito

2 3 收藏

资源整理者简介:贺贺

生命本无意义,你给它什么意义,它就有什么意义。我爱程序员。 个人主页 · 贡献了5个资源


直接登录
最新评论

推荐关注

按分类快速查找

关于资源导航
  • 伯乐在线资源导航收录优秀的工具资源。内容覆盖开发、设计、产品和管理等IT互联网行业相关的领域。目前已经收录 1439 项工具资源。
    推送伯乐头条热点内容微信号:jobbole 分享干货的技术类微信号:iProgrammer