Mockito鸡尾酒第一杯 单测Mock
鸡尾酒
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的更多相关文章
- 使用Groovy+Spock轻松写出更简洁的单测
当无法避免做一件事时,那就让它变得更简单. 概述 单测是规范的软件开发流程中的必不可少的环节之一.再伟大的程序员也难以避免自己不犯错,不写出有BUG的程序.单测就是用来检测BUG的.Java阵营中,J ...
- 你真的会写单测吗?TDD初体验
前言: 昨天读到了一篇文章,讲的是TDD,即Test-Driven Development,测试驱动开发.大体意思是,它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过 ...
- 【spock】单测竟然可以如此丝滑
0. 为什么人人都讨厌写单测 在之前的关于swagger文章里提到过,程序员最讨厌的两件事,一件是别人不写文档,另一件就是自己写文档.这里如果把文档换成单元测试也同样成立. 每个开发人员都明白单元测试 ...
- 如何优雅地执行dubbo"单测"
很多小伙伴所在的公司是基于Dubbo来构建技术栈的,日常开发中必不可少要写dubbo单测(单元测试),如果单测数据依赖已有的外部dubbo服务,一般是mock数据,如果数据比较复杂,其实mock数据也 ...
- 使用Java函数接口及lambda表达式隔离和模拟外部依赖更容易滴单测
概述 单测是提升软件质量的有力手段.然而,由于编程语言上的支持不力,以及一些不好的编程习惯,导致编写单测很困难. 最容易理解最容易编写的单测,莫过于独立函数的单测.所谓独立函数,就是只依赖于传入的参数 ...
- 用Python编写的第一个回测程序
用Python编写的第一个回测程序 2016-08-06 def savfig(figureObj, fn_prefix1='backtest8', fn_prefix2='_1_'): import ...
- Java 单测 回滚
Java 在单测的时候 需要做回滚 设置如下: 需要添加以下 注解 在类上 defaultRollback = true : 为 默认全部回滚 defaultRollback = false : 为 ...
- 输入输出无依赖型函数的GroovySpock单测模板的自动生成工具(上)
目标 在<使用Groovy+Spock轻松写出更简洁的单测> 一文中,讲解了如何使用 Groovy + Spock 写出简洁易懂的单测. 对于相对简单的无外部服务依赖型函数,通常可以使用 ...
- 一分钟了解ruby中的单测
之前用gtest写过很多c++的单测case, 对gtest的强大和灵活印象深刻:最近需要用ruby写一个小工具, 接触了下ruby, 写了代码就要写单测啊(好的单测确实对代码的健壮性和正确性保证上太 ...
随机推荐
- 面试题之----禁掉cookie的session使用方案
方式一:通过 url 传值,把session id附加到url上 缺点:整个站点中不能有纯静态页面,因为纯静态页面session id 将无法继续传到下一页面 方式二:通过隐藏表单,把session ...
- java动态代理——字段和方法字节码的基础结构及Proxy源码分析三
前文地址:https://www.cnblogs.com/tera/p/13280547.html 本系列文章主要是博主在学习spring aop的过程中了解到其使用了java动态代理,本着究根问底的 ...
- PHP Session 变量
PHP Session PHP session 变量用于存储关于用户会话(session)的信息,或者更改用户会话(session)的设置.Session 变量存储单一用户的信息,并且对于应用程序中的 ...
- PHP lstat() 函数
定义和用法 lstat() 函数返回关于文件或符号连接的信息. 该函数将返回一个包含下列元素的数组: [0] 或 [dev] - 设备编号 [1] 或 [ino] - inode 编号 [2] 或 [ ...
- PHP ignore_user_abort() 函数
实例 设置为 false(默认)- 与客户机断开会终止脚本的执行: <?phpignore_user_abort();?>高佣联盟 www.cgewang.com 上面代码的输出如下: 0 ...
- 7.18 NOI模拟赛 树论 线段树 树链剖分 树的直径的中心 SG函数 换根
LINK:树论 不愧是我认识的出题人 出的题就是牛掰 == 他好像不认识我 考试的时候 只会写42 还有两个subtask写挂了 拿了37 确实两个subtask合起来只有5分的好成绩 父亲能转移到自 ...
- 性能分析(3)- 短时进程导致用户 CPU 使用率过高案例
性能分析小案例系列,可以通过下面链接查看哦 https://www.cnblogs.com/poloyy/category/1814570.html 系统架构背景 VM1:用作 Web 服务器,来模拟 ...
- ES与Javscript,JScript,ActionScript等脚本
ES是一种语言标准,而后面的javascript.JScript.Actionscript都是基于ES的扩展语言. 实际上:javascript=ES+DOM+BOM 显然,JavaScript,JS ...
- LVS-NAT:搭建HTTP及HTTPS负载均衡集群
目录 LVS-NAT:搭建HTTP及HTTPS负载均衡集群 环境说明: 搭建NAT模式的HTTP负载集群 1. 配置好IP地址信息 2. DR上开启IP转发 3.DR上配置lvs-nat的转发机制 4 ...
- ios 浅谈一下UITextFiled UITextView 在tableview的cell上边展示
最近在项目中.要做到在tableview的cell上边加一个输入框.允许用户输入. 1.我首先选的是在uitextView 然后在通知键盘出现的时候,将tableview的内容设置在键盘的上边.但是 ...