You need to enable JavaScript to run this app. pytest中无法mock已mock对象的方法?call_count统计为0
优惠活动
大模型
产品
解决方案
定价
更多

pytest中无法mock已mock对象的方法?call_count统计为0

报错根因

你的断言跟错了mock对象:

  • 用@patch("myfile.psutil")替换模块后,psutil_.Process是对应Process类的类mock
  • 代码里parent = psutil.Process()执行时,会调用这个类mock生成一个独立的实例mock,这个实例mock默认挂在类mock的return_value属性上
  • 你写的psutil_.Process.children.call_count统计的是类mock本身带的children方法的调用数,但实际代码里调用children的是刚才生成的实例mock,两个是完全独立的mock对象,所以永远抓不到调用记录,才会出现assert 0 ==1的错误。

你打印的输出刚好能验证这个逻辑:

<MagicMock name='psutil.Process()' id='3001903696'>
<MagicMock name='psutil.Process().children()' id='3000968624'>
第一行打印的parent就是类mock返回的实例,后续调用的children方法就是挂在这个实例下面的。

修正后的测试代码

把断言的追踪对象换成类mock的return_value(也就是真实代码里拿到的parent实例)就行:

@patch("myfile.psutil")
def test_run_post_request(self, psutil_, runnable_object):
    # 拿到psutil.Process()调用返回的实例mock
    mock_parent = psutil_.Process.return_value
    runnable_object.run()
    # 原来校验类调用次数的断言是对的,保留
    assert psutil_.Process.call_count == 1
    # 改断言对象,统计实例上的children方法调用次数
    assert mock_parent.children.call_count == 1
    # 还可以顺手加个参数校验,确认children是按要求传recursive=True调用的
    mock_parent.children.assert_called_once_with(recursive=True)
其他patch方式的常见坑

之前你试的几种patch写法报错逻辑都是一样的:

  • 用@patch("myfile.psutil.Process")时,同样返回类mock,必须通过psutil_.Process.return_value拿实例mock做断言,不能直接盯着类mock本身的children方法
  • 用@patch("myfile.psutil.Process.children")时,一定要patch myfile模块里绑定的Process类上的children方法,别直接patch原psutil库里的类方法,不然会因为导入时的引用绑定问题抓不到实际调用

内容的提问来源于stack exchange,提问作者user3302735

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 13:36:02