惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
爱范儿
爱范儿
H
Help Net Security
V
Visual Studio Blog
J
Java Code Geeks
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
Apple Machine Learning Research
Apple Machine Learning Research
MyScale Blog
MyScale Blog
The Cloudflare Blog
Martin Fowler
Martin Fowler
D
Docker
腾讯CDC
F
Fortinet All Blogs
雷峰网
雷峰网
GbyAI
GbyAI
G
Google Developers Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Recent Announcements
Recent Announcements
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Blog — PlanetScale
Blog — PlanetScale
Engineering at Meta
Engineering at Meta
博客园 - 聂微东
博客园 - 叶小钗

博客园 - gogoy

LangChain的Deep Agents学习 Java 开发中 一篇文章讲清楚VO,BO,PO,DO,DTO的区别 云原生:Mesh化架构模式(sidecar模式)、容器vsPod Serverless 介绍 Spring单例Bean并发安全问题分析和解决 图解直接映射(Direct mapped)、全相联(Fully-associative)和组相联(Set-associative)cache缓存基本原理 为什么大语言模型推理要分成 Prefill 和 Decode? 【台大机器学习系列1】机器学习2021 人工智能交互中的角色与提示词:System、User与Assistant 台大李宏毅 2025 AI Agent 新课来了!(即李宏毅机器学习2025) 一文搞懂Passkey(转) RISC-V、x86、ARM技术对比解析 各种函数依赖及规范化解决 SSE协议与HTTP协议 操作日志 “二清”详解:支付产品必须知道的“清结算规矩” 金融通识:国内支付清算体系CNAPS2 zookeeper TCP相关经典 Java常见的超时及设计
Mockito教程(单测mock)
gogoy · 2024-08-27 · via 博客园 - gogoy

1 Mockito 介绍 [3]

1.1 Mockito是什么?

Mockito是mocking框架,它让你用简洁的API做测试。而且Mockito简单易学,它可读性强和验证语法简洁。

1.2 为什么需要Mock

测试驱动的开发( TDD)要求我们先写单元测试,再写实现代码。在写单元测试的过程中,我们往往会遇到要测试的类有很多依赖,这些依赖的类/对象/资源又有别的依赖,从而形成一个大的依赖树,要在单元测试的环境中完整地构建这样的依赖,是一件很困难的事情。如下图所示:

为了测试类A,我们需要Mock B类和C类(用虚拟对象来代替)如下图所示:

1.3 Stub和Mock异同[1]

  • 相同:Stub和Mock都是模拟外部依赖
  • 不同:Stub是完全模拟一个外部依赖, 而Mock还可以用来判断测试通过还是失败

在软件测试中,"Stub"(桩)和"Mock"(模拟)都是用来替代或模仿实际组件的测试工具,用于隔离被测系统的一部分,从而可以专注于测试某一个具体的模块。尽管它们有相似的目的,但在使用方式和功能上有一些关键区别:

1. **Stub(桩)**:
- Stub是一种简单的替代对象,通常用于模拟复杂的系统或外部服务。它提供固定的响应或行为,这些响应或行为是预先定义好的,不需要根据输入动态变化。
- Stub主要用于控制测试环境,在测试过程中提供一致性和可预测性。
- 它们通常比较简单,可能只是简单地返回一个预设的数据集或者执行一个预定义的操作
- Stub常用于当一个组件需要与数据库或其他外部系统交互时,但测试时并不关心这些系统的具体实现细节。

2. **Mock(模拟)**:
- Mock对象比Stub更复杂,它不仅可以模拟对象的行为还可以记录和验证方法调用的次数以及顺序
- Mock允许你在测试时指定期望的方法调用,并检查这些调用是否按预期发生。如果方法没有按照预期的方式被调用,Mock可能会抛出异常或失败。
- Mock也可以设置预期的返回值,甚至可以根据传入的不同参数返回不同的结果。
- 使用Mock时,你可以更精细地控制测试条件,并且能够验证代码中的逻辑是否正确地处理了各种情况。

总结来说,Stub主要用于提供静态的或固定的行为,而Mock则更多地用于验证对象之间的交互是否符合预期。在实际开发中,根据测试的具体需求选择合适的工具是非常重要的。

2 使用Mockito [2][4]

2.1 验证行为

 1 @Test
 2     public void verify_behaviour(){
 3         //模拟创建一个List对象
 4         List mock = mock(List.class);
 5         //使用mock的对象
 6         mock.add(1);
 7         mock.clear();
 8         //验证add(1)和clear()行为是否发生
 9         verify(mock).add(1);
10         verify(mock).clear();
11     }

2.2 模拟我们所期望的结果

@Test
    public void when_thenReturn(){
        //mock一个Iterator类
        Iterator iterator = mock(Iterator.class);
        //预设当iterator调用next()时第一次返回hello,第n次都返回world
        when(iterator.next()).thenReturn("hello").thenReturn("world");
        //使用mock的对象
        String result = iterator.next() + " " + iterator.next() + " " + iterator.next();
        //验证结果
        assertEquals("hello world world",result);
    }

1 @Test(expected = IOException.class)
2     public void when_thenThrow() throws IOException {
3         OutputStream outputStream = mock(OutputStream.class);
4         OutputStreamWriter writer = new OutputStreamWriter(outputStream);
5         //预设当流关闭时抛出异常
6         doThrow(new IOException()).when(outputStream).close();
7         outputStream.close();
8     }