鸡尾酒

Mockito是Java的单元测试Mock框架。

它的logo是一杯古巴最著名的鸡尾酒Mojito,

Mojito鸡尾酒,源自古巴的哈瓦那,带有浓厚的加勒比海风情。

并不浓烈,但是喝一杯下去,脸上会泛起红晕,象少女的羞涩。味道很清新,有一点青涩、有点甜蜜。

巧的是,我才发现周董的新歌,也叫《Mojito》。哈哈哈。

Stub & Mock

Stub和Mock是Test Double类型中的2种。Test Double一共有5种类型,Dummy,Stub,Spy,Mock,Fake。

Test Double是测试复制品,用来统称模拟真实对象的假对象。因使用场景有略微不同,而有这5种类型。

  • Dummy,通常只用来填充参数列表。有可能是null对象引用,或Object类实例等。
  • Fake,是简化版的实现,比如基于内存实现的数据库,不会真的去做数据库操作,用简单的HashMap来存放数据。
  • Stub,Stub用来替代SUT(System Under Test)依赖的组件,但是只模拟一个外部依赖,不做断言。
  • Spy,介于Stub和Mock之间。如果真实对象没有被打桩,当调用Spy对象时,真实对象也会被调用。
  • Mock,可以理解为Stub+Verification,既模拟外部依赖,也会定义预期结果。

不管你有没有懵逼,反正我是懵逼了。不着急,慢慢来,先搞懂Stub和Mock。

看一个实例,发送邮件,

public interface MailService {
public void send(Message msg);
}

先写个Stub,

public class MailServiceStub implements MailService {
private List<Message> messages = new ArrayList<Message>(); public void send(Message msg) {
messages.add(msg);
} public int numberSent() {
return messages.size();
}
}

实现Stub的状态验证,

class OrderStateTester...

public void testOrderSendsMailIfUnfilled() {
Order order = new Order(TALISKER, 51);
MailServiceStub mailer = new MailServiceStub();
order.setMailer(mailer);
order.fill(warehouse);
assertEquals(1, mailer.numberSent());
}

只做了简单的测试,断言发出了1封邮件。没有测试是否发送给了对的收件人,或者邮件正文是否正确。不过不影响跟Mock比较。

如果用Mock,会怎么写呢?

class OrderInteractionTester...

public void testOrderSendsMailIfUnfilled() {
Order order = new Order(TALISKER, 51);
Mock warehouse = mock(Warehouse.class);
Mock mailer = mock(MailService.class);
order.setMailer((MailService) mailer.proxy()); mailer.expects(once()).method("send");
warehouse.expects(once()).method("hasInventory")
.withAnyArguments()
.will(returnValue(false)); order.fill((Warehouse) warehouse.proxy());
}

结合一张图,就一下全明白了,

怎么喝Mockito?

添加Maven dependency,

<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>3.3.3</version>
<scope>test</scope>
</dependency>

现在可以开始Mock了,先Mock一个List Interface试试,(示例只是玩语法,实际应使用instance)

//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
verify(mockedList).add("one");
verify(mockedList).clear();

接着用Mockito来做Stub,淡定,我知道你在怀疑什么。我们在实际使用的时候,不要被理论的概念限制了。Mockito为什么不能Stub,Stub不就是模拟外部依赖嘛,模拟了不就是Stub了嘛。

// 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)); // Although it is possible to verify a stubbed invocation, usually it's just redundant
// If your code cares what get(0) returns, then something else breaks
// (often even before verify() gets executed).
// If your code doesn't care what get(0) returns, then it should not be stubbed.
verify(mockedList).get(0);

mock默认会返回null,或原始值,或空集合。如int/Integer返回0,boolean/Boolean返回false。

第一杯先打个样,喝完这杯,还有“三”杯。

参考资料

https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/Mockito.html

https://martinfowler.com/articles/mocksArentStubs.html

[http://xunitpatterns.com/Test Double.html](http://xunitpatterns.com/Test Double.html)


专注测试,坚持原创,只做精品。欢迎关注公众号『东方er』

版权申明:本文为博主原创文章,转载请保留原文链接及作者。

Mockito鸡尾酒第一杯 单测Mock的更多相关文章

  1. 使用Groovy+Spock轻松写出更简洁的单测

    当无法避免做一件事时,那就让它变得更简单. 概述 单测是规范的软件开发流程中的必不可少的环节之一.再伟大的程序员也难以避免自己不犯错,不写出有BUG的程序.单测就是用来检测BUG的.Java阵营中,J ...

  2. 你真的会写单测吗?TDD初体验

    前言: 昨天读到了一篇文章,讲的是TDD,即Test-Driven Development,测试驱动开发.大体意思是,它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过 ...

  3. 【spock】单测竟然可以如此丝滑

    0. 为什么人人都讨厌写单测 在之前的关于swagger文章里提到过,程序员最讨厌的两件事,一件是别人不写文档,另一件就是自己写文档.这里如果把文档换成单元测试也同样成立. 每个开发人员都明白单元测试 ...

  4. 如何优雅地执行dubbo"单测"

    很多小伙伴所在的公司是基于Dubbo来构建技术栈的,日常开发中必不可少要写dubbo单测(单元测试),如果单测数据依赖已有的外部dubbo服务,一般是mock数据,如果数据比较复杂,其实mock数据也 ...

  5. 使用Java函数接口及lambda表达式隔离和模拟外部依赖更容易滴单测

    概述 单测是提升软件质量的有力手段.然而,由于编程语言上的支持不力,以及一些不好的编程习惯,导致编写单测很困难. 最容易理解最容易编写的单测,莫过于独立函数的单测.所谓独立函数,就是只依赖于传入的参数 ...

  6. 用Python编写的第一个回测程序

    用Python编写的第一个回测程序 2016-08-06 def savfig(figureObj, fn_prefix1='backtest8', fn_prefix2='_1_'): import ...

  7. Java 单测 回滚

    Java 在单测的时候 需要做回滚 设置如下: 需要添加以下 注解 在类上 defaultRollback = true : 为 默认全部回滚 defaultRollback = false : 为 ...

  8. 输入输出无依赖型函数的GroovySpock单测模板的自动生成工具(上)

    目标 在<使用Groovy+Spock轻松写出更简洁的单测> 一文中,讲解了如何使用 Groovy + Spock 写出简洁易懂的单测. 对于相对简单的无外部服务依赖型函数,通常可以使用 ...

  9. 一分钟了解ruby中的单测

    之前用gtest写过很多c++的单测case, 对gtest的强大和灵活印象深刻:最近需要用ruby写一个小工具, 接触了下ruby, 写了代码就要写单测啊(好的单测确实对代码的健壮性和正确性保证上太 ...

随机推荐

  1. [转]十分钟带你理解Kubernetes核心概念

    本文将会简单介绍 Kubernetes的核心概念.因为这些定义可以在Kubernetes的文档中找到,所以文章也会避免用大段的枯燥的文字介绍.相反,我们会使用一些图表(其中一些是动画)和示例来解释这些 ...

  2. Qt-绘制图表

    1  简介 使用Qt的charts模块来绘制图表,案例来自Qt自带的demo. charts模块简介:Qt Chars模块提供了一系列容易使用的图表组件.需要使用charts组件时,需要导入Qt Ch ...

  3. 一周一个中间件-ES搜索引擎

    ---toc: truetitle: 一周一个中间件-ES搜索引擎date: 2019-09-19 18:43:36tags: - 中间件 - 搜索引擎--- ## 前言 > 在众多搜索引擎中, ...

  4. scp的使用以及cp的对比

    scp是secure copy的简写,用于在Linux下进行远程拷贝文件的命令,和它类似的命令有cp,不过cp只是在本机进行拷贝不能跨服务器,而且scp传输是加密的.可能会稍微影响一下速度.当你服务器 ...

  5. mongodb因为上一次异常关闭导致锁死,连接失败

    之前一直可以用,但是突然在启动node,服务端的时候报错,(下面的错误信息都是复制的网上的报错信息,刚才忘记截图错误信息了,现在已经解决问题) 这是服务端的报错 (node:17453) Unhand ...

  6. PHP 太空船运算符(组合比较符)

    PHP 7 新增加的太空船运算符(组合比较符)用于比较两个表达式 $a 和 $b,如果 $a 小于.等于或大于 $b时,它分别返回-1.0或1. 实例 <?php // 整型比较 print( ...

  7. PHP unixtojd() 函数

    ------------恢复内容开始------------ 实例 把 Unix 时间戳转换为儒略日计数: <?phpecho unixtojd();?> 运行实例 » 定义和用法 uni ...

  8. PHP deg2rad() 函数

    实例 把角度转换为弧度: <?phpecho deg2rad("45") . "<br>";echo deg2rad("90&quo ...

  9. PHP getNamespaces() 函数

    实例 返回 XML 文档中使用的命名空间: <?php$xml=<<<XML高佣联盟 www.cgewang.com<?xml version="1.0&quo ...

  10. 企业玩转DevOps转型:由弱到强,只需7步

    [摘要] 在参考业界方法并总结客户成功故事的基础上,本文提出了“七步法”路线图,希望能帮助更多的企业顺利进行DevOps转型. 从2009年诞生,DevOps已经悄然走过了10多个年头.Gartner ...