Python中如何测试被Mock的数据类调用?解决测试匹配错误
问题原因
当你用unittest.mock.patch替换Person类时,被patch后的Person是一个Mock对象,它会完整跟踪所有调用链:
- 每次
Person()实例化操作,本质是调用Mock类的__call__方法,会被记录为call(); - 实例化后调用
work()方法,会被Mock记录为call().work()——这是因为Mock会把实例化返回的子Mock对象的方法调用,以链式形式记录在父Mock的调用记录里。
你的测试断言只预期两次call(),但实际mock_calls里会包含call()和call().work()各两次,自然会匹配失败。
正确测试方法
根据你的需求(验证两次实例化+两次work调用),可以分两种方式编写测试:
方式1:直接验证实例化次数和方法调用次数
这是最简洁的写法,分别验证类被实例化的次数,以及每个实例的work方法被调用的次数:
import unittest from unittest.mock import patch from your_module import run_person # 替换成你的实际模块名 class TestRunPerson(unittest.TestCase): @patch("your_module.Person") # 注意路径要和run_person里导入Person的路径一致 def test_run_person(self, mock_person): run_person() # 验证Person被实例化了2次 mock_person.assert_called_times(2) # 验证所有实例的work方法总共被调用2次 mock_person.return_value.work.assert_called_times(2)
方式2:精确验证调用顺序(如果需要)
如果你需要严格验证实例化和方法调用的顺序,可以直接检查完整的调用链:
import unittest from unittest.mock import patch, call from your_module import run_person class TestRunPerson(unittest.TestCase): @patch("your_module.Person") def test_run_person(self, mock_person): run_person() # 预期的完整调用链:实例化→调work,再实例化→调work expected_calls = [ call(), call().work(), call(), call().work() ] mock_person.assert_has_calls(expected_calls, any_order=False)
关键注意点
- patch的路径必须和
run_person函数中导入Person的路径一致,否则patch不会生效; mock_person.return_value代表每次实例化返回的Mock实例,所以它的work方法调用次数就是所有实例调用work的总次数。
内容的提问来源于stack exchange,提问作者aura
相关产品推荐
相关产品推荐

