侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

解释Mock与Stub的区别及使用场景

2025-12-11 / 0 评论 / 9 阅读

题目

解释Mock与Stub的区别及使用场景

信息

  • 类型:问答
  • 难度:⭐

考点

Mock概念,Stub概念,测试替身区别,使用场景

快速回答

Mock和Stub都是测试替身(Test Doubles),用于隔离被测对象的外部依赖:

  • Stub:提供预定义响应的简单替代品,用于控制测试输入
  • Mock:验证对象间交互行为的替身,关注方法调用细节
  • 关键区别:Stub关注状态(返回什么),Mock关注行为(如何调用)
## 解析

1. 核心概念

Stub(桩):模拟依赖对象的简单实现,返回预设的固定响应。例如硬编码返回特定值或异常。

Mock(模拟对象):记录并验证与被测对象的交互细节(如方法调用次数、参数值)。

2. 代码示例

// Stub示例:模拟支付接口
class PaymentStub {
  process(amount) {
    return { success: true }; // 硬编码成功响应
  }
}

// Mock示例:使用Jest验证调用
test('should send email once', () => {
  const emailServiceMock = {
    send: jest.fn() // 创建Mock函数
  };

  userService.notifyUser(emailServiceMock);
  expect(emailServiceMock.send).toHaveBeenCalledTimes(1); // 验证调用次数
});

3. 使用场景对比

场景Stub适用Mock适用
需要固定返回值✅(如模拟数据库返回测试数据)
验证对象交互行为✅(如检查邮件是否发送)
触发异常路径✅(如模拟网络错误)

4. 最佳实践

  • 优先使用Stub:当仅需控制依赖输出时(更简单稳定)
  • 谨慎使用Mock:过度验证会导致测试脆弱(如验证具体参数而非结果)
  • 遵循"Stub Queries, Mock Actions"原则:查询操作用Stub,命令操作用Mock

5. 常见错误

  • 混淆概念:在不需要验证行为时使用Mock增加复杂度
  • 过度指定:用Mock验证非核心交互(如内部私有方法调用)
  • 忽略清理:未重置全局Mock状态影响其他测试

6. 扩展知识

  • 其他测试替身:Dummy(空对象)、Fake(简易实现如内存数据库)、Spy(记录调用的Stub)
  • 工具推荐:Jest(JavaScript)、Mockito(Java)、unittest.mock(Python)
  • 设计影响:过度依赖Mock可能表明代码耦合度高,需考虑重构