首页/开发/软件测试速查/pytest-mock 的 mocker 夹具
自动化测试66 条

pytest-mock 的 mocker 夹具

pytest-mock 提供 mocker 夹具封装 patch/spy,随用例自动清理;相比手写 unittest.mock 上下文样板更少,且能与 fixture 系统组合。

软件测试速查开发更新于 2026-10-13

pytest-mock 的 mocker 夹具是什么

pytest-mock 提供 mocker 夹具,封装 unittest.mock 的 patch 与 spy,随用例自动清理:相比手写上下文管理器样板更少,还能与 fixture 系统组合。它适合替换依赖模块的行为、记录调用次数与参数,用例结束后统一还原,不留全局残留。

基本信息

核心对象mocker 夹具,封装 patch 与 spy
清理用例结束自动还原,无需 with 与 addCleanup
常用方法patch、spy、stub、patch.object、patch.dict
断言接口assert_called_once、assert_called_with 等来自 Mock
适用边界替换依赖与外部协作对象,不深入被测内部实现

补丁与间谍

补丁与间谍
def test_submit(mocker):
    # 替换依赖并断言调用
    send = mocker.patch("app.mailer.send", return_value=True)
    order.submit()
    send.assert_called_once()


def test_spy(mocker):
    # 间谍:保留原实现,只记录调用
    spy = mocker.spy(cart, "total")
    cart.checkout()
    spy.assert_called()

典型使用场景

  • 隔离外部依赖:邮件、支付、短信调用替换为桩。
  • 调用契约:断言调用次数与关键参数,验证协作协议。
  • 失败演练:让依赖抛异常,验证重试与降级路径。
  • 部分替换:spy 保留原实现只做观察记录。
  • 字典与配置:patch.dict 临时覆盖配置项。
  • 样板收敛:把散落的 unittest.mock 样板收敛到 mocker。

常用方法

方法行为场景
patch替换目标并返回 Mock依赖隔离
spy保留实现、记录调用观察协作
stub替换并返回默认值占位
patch.dict临时改字典内容配置覆盖
替换范围尽量止步于依赖模块,不要深入到被测对象的内部实现,避免断言绑定实现细节。
patch 目标遵循「patch 使用方」原则:from x import y 之后,要 patch 使用方模块里的名字。

断言要点

  • 调用次数:assert_called_once 与 call_count 结合看。
  • 调用参数:assert_called_with 校验关键参数,避免只数次数。
  • 调用顺序:多个依赖间用 mock_calls 核对相对顺序。
  • 未调用断言:assert_not_called 验证短路与缓存路径。
打桩建议带 spec:以真实对象为规格创建 Mock,拼错的属性或参数会直接报错,而不是静默通过。
mock 嵌套保持在一层:多层 mock 让断言脆弱,必要时改造为接口级桩。

易错点

  • patch 目标写错:from x import y 之后应 patch 使用方模块里的名字
  • 对私有方法大量打桩,重构即失败,用例维护成本上升
  • 只断言被调用不校验参数,错误参数仍然通过
  • 桩的返回值与真实依赖漂移,测试与线上行为脱节
  • 全量 mock 后测试只剩自说自话,失去发现缺陷的能力
  • Mock 不带规格,接口改名后测试仍然通过
  • 在模块级共享同一个 mock 对象,用例间互相覆盖调用记录

数据来源与参考

  • pytest-mock 官方文档(pytest-mock.readthedocs.io)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌