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
相关产品推荐
相关产品推荐

