Mock与Stub


一、核心概念与差异对比

特性MockStub
核心目的验证对象间的交互行为提供预定义的固定响应
验证重点方法调用次数、参数、顺序不关注调用过程,只关注结果
行为模拟可编程的智能模拟静态的简单响应
适用场景验证协作关系隔离依赖、提供固定数据
复杂性较高(需要设置预期行为)较低(简单硬编码响应)

架构决策点:选择Mock还是Stub取决于测试目标 - 验证交互行为用Mock,替换依赖项用Stub


二、架构设计中的分层应用

测试金字塔中的定位
UI Tests
Integration Tests
Unit Tests
Mock
Stub
  • 单元测试层:Mock主导(验证类间协作)
  • 集成测试层:Stub主导(模拟外部依赖)
  • 端到端测试:真实依赖(不使用模拟)
Spring测试架构
// 典型Spring测试分层
@SpringBootTest // 集成测试
class IntegrationTest {@MockBean DependencyService service; // MockBean替代真实依赖@Test void testIntegration() {// 使用Stub提供预设数据given(service.getData()).willReturn(new Data("stub value"));}
}@ExtendWith(MockitoExtension.class) // 单元测试
class UnitTest {@Mock Dependency dependency;@InjectMocks ServiceUnderTest service;@Test void testBehavior() {// 设置Mock行为并验证交互when(dependency.process(any())).thenReturn(true);service.execute();verify(dependency, times(1)).process(any());}
}

三、Spring生态中的实现详解

1. Stub实现方案

场景:为支付网关提供测试响应

// 定义支付网关接口
public interface PaymentGateway {PaymentResult charge(Order order);
}// 创建Stub实现
public class StubPaymentGateway implements PaymentGateway {private final PaymentResult fixedResult;public StubPaymentGateway(PaymentResult result) {this.fixedResult = result;}@Overridepublic PaymentResult charge(Order order) {// 静态响应,不包含业务逻辑return fixedResult;}
}// 测试中使用
@Test
void testOrderProcessingWithStub() {// 创建带成功响应的StubPaymentGateway stubGateway = new StubPaymentGateway(new PaymentResult("SUCCESS", "TX-123"));OrderService service = new OrderService(stubGateway);Order order = new Order(100.0);service.process(order);assertThat(order.getStatus()).isEqualTo(OrderStatus.PAID);
}
2. Mock实现方案(Mockito框架)

场景:验证库存服务调用

@ExtendWith(MockitoExtension.class)
class InventoryServiceTest {@Mock InventoryRepository mockRepo; // 创建Mock对象@InjectMocks InventoryService inventoryService; // 注入被测试对象@Testvoid shouldUpdateInventoryWhenOrderPaid() {// 准备测试数据Order order = new Order("order-1");order.addItem("prod-001", 2);// 设置Mock行为when(mockRepo.findByProductId("prod-001")).thenReturn(new Inventory("prod-001", 10));// 执行测试inventoryService.updateInventory(order);// 验证交互行为verify(mockRepo, times(1)).findByProductId("prod-001");verify(mockRepo, times(1)).save(argThat(inv -> inv.getQuantity() == 8)); // 验证保存参数// 验证未发生的方法调用verify(mockRepo, never()).delete(any());}
}

四、高级模式与应用场景

1. 部分Mock(Spy对象)

场景:测试复杂服务中的特定方法

@Spy // 部分Mock:真实对象+可Mock特定方法
private EmailService emailService;@Test
void testOrderNotification() {// 模拟发送邮件方法doNothing().when(emailService).sendConfirmation(any());orderService.processOrder(order);verify(emailService).sendConfirmation(order);
}
2. Spring Cloud Contract(契约测试)

架构方案:跨服务边界的Stub管理

生成Stub
测试时下载
Provider
Stub Repository
Consumer

提供方(定义契约):

// payment-contract.groovy
Contract.make {request {method POST()url '/payments'body([orderId: anyUuid(),amount: anyPositiveDouble()])}response {status 201body([status: "SUCCESS",transactionId: regex('[0-9a-f]{8}-[0-9a-f]{4}')])}
}

消费方(测试中使用Stub):

@SpringBootTest
@AutoConfigureStubRunner(ids = "com.example:payment-service:+:stubs")
class OrderServiceContractTest {@Testvoid shouldProcessPayment() {PaymentResult result = paymentClient.charge(new PaymentRequest(...));assertThat(result.getStatus()).isEqualTo("SUCCESS");}
}

五、架构师的最佳实践建议

  1. 分层使用策略

    • 单元测试:80% Mock + 20% Stub
    • 集成测试:20% Mock + 80% Stub
    • 契约测试:100% Stub(基于提供方契约)
  2. 性能优化

    // 重用Mock对象提升测试速度
    @MockitoSettings(strictness = Strictness.LENIENT)
    public class ReusableMocksTest {@Mock static DatabaseConnection sharedConnection;
    }
    
  3. 反模式警示

    • ❌ 过度验证:verify(mock, times(3)).trivialMethod()
    • ❌ Mock传递:when(mockA.call()).thenReturn(mockB)
    • ❌ 脆弱的Stub:硬编码不合理的测试数据
  4. 现代替代方案

    • 虚拟服务(Testcontainers):代替Stub提供更真实的模拟
    @Container
    static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");
    
    • 代码生成Stub(OpenAPI Generator):基于API规范自动生成

六、架构决策树

graph TDA[需要测试什么?] A --> B{验证对象交互?}B -->|是| C[使用Mock]B -->|否| D{需要控制依赖行为?}D -->|是| E[使用Stub]D -->|否| F[使用真实对象]C --> G{需要部分真实行为?}G -->|是| H[使用Spy]G -->|否| I[使用纯Mock]E --> J{跨服务边界?}J -->|是| K[使用契约测试Stub]J -->|否| L[使用简单Stub实现]

作为系统架构师,我建议:在保证测试质量的前提下选择最简单的模拟方案。Mock适合验证内部协作,Stub适合隔离外部依赖,契约测试Stub则是微服务架构的必备工具。正确使用这些技术可以构建快速、可靠且维护成本低的测试体系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/92519.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/92519.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

香港服务器容器网络插件的多节点通信性能基准测试

香港服务器容器网络插件的多节点通信性能基准测试在云计算和容器化技术快速发展的今天&#xff0c;香港服务器因其优越的地理位置和网络环境&#xff0c;成为众多企业部署容器服务的首选。本文将深入探讨香港服务器环境下容器网络插件的多节点通信性能&#xff0c;通过详实的基…

Vue3 学习教程,从入门到精通,Vue 3 全局 API 语法知识点及案例详解(32)

Vue 3 全局 API 语法知识点及案例详解 Vue 3 提供了丰富的全局 API&#xff0c;用于创建应用实例、注册全局组件、指令、插件等。以下将详细介绍 Vue 3 的主要全局 API&#xff0c;并结合详细的案例代码进行说明。每个案例代码都包含中文注释&#xff0c;帮助初学者更好地理解…

UE5多人MOBA+GAS 41、制作一个飞弹,添加准心索敌

文章目录添加新角色&#xff08;不写了&#xff09;创建一个发射技能创建一个飞弹类添加击中特效添加准星UI获取瞄准目标添加新角色&#xff08;不写了&#xff09; 将原本的机器人蓝图改为BP_PlayerCharacter&#xff0c;以此创建子蓝图 创建动画蓝图模板&#xff08;具体就…

解决渲染抖动与滚动锚点定位不准确问题的方法与经验分享

场景描述&#xff1a;React 虚拟列表&#xff08;Virtualized List&#xff09;是当我们在处理大列表时&#xff0c;为了提升性能而采用的一种技术。然而在实现过程中&#xff0c;可能会遇到渲染抖动问题以及滚动锚点定位不准确的问题。  解决方案&#xff1a;React虚拟列表实…

OpenAI 时隔多年再开源!GPT-OSS 120B/20B 发布,支持本地部署,消费级 GPU 即可运行

OpenAI 近期做出了一项令人瞩目的战略转变&#xff1a;宣布推出两款开放权重&#xff08;Open Weight&#xff09; 语言模型 GPT-OSS-120B 和 GPT-OSS-20B。这不仅是其自 GPT-2 之后首次开源模型&#xff0c;更关键的是&#xff0c;这两款模型特别针对消费级硬件进行了深度优化…

MySQL高可用方案之MySQL Group Replication高可用架构搭建完全指南

MySQL Group Replication高可用架构搭建完全指南 前言 在当今互联网应用中,数据库高可用性已成为系统设计的核心需求。MySQL作为最流行的开源关系型数据库之一,其高可用解决方案备受关注。MySQL Group Replication是MySQL官方推出的原生高可用解决方案,它基于Paxos协议实现…

网站SSL证书到期如何更换?简单完整操作指南

----------------------------------------------------------------------------------------------- 这是我在我的网站中截取的文章&#xff0c;有更多的文章欢迎来访问我自己的博客网站rn.berlinlian.cn&#xff0c;这里还有很多有关计算机的知识&#xff0c;欢迎进行留言或…

Spring Boot 开发三板斧:POM 依赖、注解与配置管理

引言 Spring Boot 是一个功能强大且广受欢迎的框架&#xff0c;用于快速构建基于 Spring 的应用。它通过简化配置和自动化管理&#xff0c;帮助开发者专注于业务逻辑的实现。然而&#xff0c;要想高效地开发 Spring Boot 应用&#xff0c;掌握以下三个关键点至关重要&#xff1…

kubernetes安装搭建

个人博客站—运维鹿:http://www.kervin24.top/ CSDN博客—做个超努力的小奚&#xff1a; https://blog.csdn.net/qq_52914969?typeblog 一、kubernetes介绍 Kubernetes本质是一组服务器集群&#xff0c;它可以在集群的每个节点上运行特定的程序&#xff0c;来对节点中的容…

MySQL高可用方案之MySQL InnoDB Cluster高可用架构实战指南:从零搭建到生产部署

MySQL InnoDB Cluster高可用架构实战指南:从零搭建到生产部署 一、引言:为什么选择MySQL InnoDB Cluster 在当今数据驱动的商业环境中,数据库高可用性已成为企业IT基础设施的核心需求。MySQL作为全球最受欢迎的开源关系型数据库,其高可用解决方案备受关注。而MySQL InnoD…

祝融号无线电工作频段

前面深入查证了旅行者1号的无线电工作频段&#xff1a; 旅行者1号无线电工作频段-CSDN博客 下面尝试查证我国祝融号无线电工作频段。 一、百度百科 来自百度百科&#xff1a; 我注意到一条关键信息&#xff1a; 这说明祝融号在国际上是有合作的&#xff0c;而不是我们国家单…

Kafka生产者相关原理

前言前面已经介绍了Kafka的架构知识并引出了Kafka的相关专业名称进行解释这次分享一下Kafka对生产者发送消息进行处理的运行机制和原理生产者发送消息两种方式同步发送消息程序中线程执行完消息发送操作之后会等待Kafka的消息回应ack默认等待30秒没有回应就会抛出异常等待时间和…

Python 获取对象信息的所有方法

在 Python 里&#xff0c;我们经常需要检查一个对象的类型、属性、方法&#xff0c;甚至它的源码。这对调试、学习和动态编程特别有用。今天我们就来聊聊获取对象信息的常见方法&#xff0c;按由浅入深的顺序来学习。 参考文章&#xff1a;Python 获取对象信息 | 简单一点学习…

vuhub Beelzebub靶场攻略

靶场下载&#xff1a; 下载地址&#xff1a;https://download.vulnhub.com/beelzebub/Beelzebub.zip 靶场攻略&#xff1a; 主机发现&#xff1a; nmap 192.168.163.1/24 端口扫描&#xff1a; nmap -p-65535 -A 192.168.163.152 发现没有额外端口。 页面扫描&#xff1…

开启单片机

前言&#xff1a;为未来拼搏的第n天&#xff0c;从单片机开始。为什么要学习单片机呢&#xff0c;单片机的工作涉及范围及其广如&#xff1a;消费电子&#xff0c;游戏机音响&#xff1b;工业控制&#xff1a;机器人控制&#xff1b;医疗设备&#xff0c;通信设备&#xff0c;物…

人工智能系列(8)如何实现无监督学习聚类(使用竞争学习)?

案例&#xff1a;鸢尾花数据集的聚类一.聚类简介神经网络能够从输入数据中自动提取有意义的特征&#xff0c;而竞争学习规则使得单层神经网络能够根据相似度将输入样本进行聚类&#xff0c;每个聚类由一个输出神经元代表并作为该类别的“原型”&#xff0c;从而实现对输入模式的…

Windows安装mamba全流程(全网最稳定最成功)

windows系统下安装mamba会遇到各种各样的问题。博主试了好几天&#xff0c;把能踩的坑都踩了&#xff0c;总结出了在windows下安装mamba的一套方法&#xff0c;已经给实验室的windows服务器都装上了。只要跟着我的流程走下来&#xff0c;大概率不会出问题&#xff0c;如果遇到其…

Autosar Dem配置-最大存储的DTC信息个数配置-基于ETAS软件

文章目录 前言 Autosar Dem相关配置 ETAS工具中的配置 生成文件分析 测试验证 总结 前言 诊断DTC开发中,会有故障快照和扩展数据的存储需求,但由于控制器的可用存储空间有限,所以无法存储所有DTC的信息,这时就需要限制存储的数量,本文介绍该参数在ETAS软件中的配置。 Au…

【MySQL】EXISTS 与 NOT EXISTS 深度解析:从原理到实战的完整指南

在复杂的业务查询中&#xff0c;我们常常需要判断“是否存在满足某条件的记录”或“找出不满足某些条件的记录”。这时&#xff0c;EXISTS 和 NOT EXISTS 子查询便成为强大的工具。它们不仅逻辑清晰、语义明确&#xff0c;而且在某些场景下性能远超 IN 或 JOIN。然而&#xff0…

面对信号在时频平面打结,VNCMD分割算法深度解密

“ 信号迷宫中的破壁者&#xff1a;VNCMD如何分解纠缠的时空密码&#xff1f;——从鲸歌到机械故障&#xff0c;宽带信号分解新纪元。”01—痛点直击&#xff1a;为什么传统方法集体失效&#xff1f;2017年&#xff0c;上海交大团队提出了一项突破性研究&#xff1a;变分非线性…