Python unittest.mock @patch装饰器模拟对象方法返回值失败问题排查
问题分析与解决方案
你遇到的问题核心在于Mock对象的实例化行为:当你用patch把DummyObject替换成你定义的dummy_patch这个Mock实例后,调用do.DummyObject()其实是触发了dummy_patch的__call__方法,而Mock的__call__默认会返回一个全新的Mock实例,不是你预先配置好的dummy_patch本身。
你之前设置的dummy_patch.foo.return_value = "9999"是作用在类级别的Mock上,但实际创建的tmp是这个Mock的调用返回值(新的Mock实例),这个新实例的foo方法并没有被设置返回值,所以它会返回默认的MagicMock对象,导致测试失败。
解决方法一:让Mock实例化时返回自身
修改你的dummy_patch配置,让它的__call__方法返回自己,这样do.DummyObject()就会直接返回你预先配置好的Mock对象:
import unittest from unittest.mock import patch, Mock import dummy_objects as do dummy_patch = Mock(spec=do.DummyObject) dummy_patch.foo.return_value = "9999" # 关键:让Mock被实例化时返回自身 dummy_patch.__call__.return_value = dummy_patch @patch("dummy_objects.DummyObject", new=dummy_patch) class TestCaseOne(unittest.TestCase): def test_patching_foo(self): tmp = do.DummyObject() self.assertEqual(tmp.foo(), "9999") # 现在测试会成功
解决方法二:在测试方法内配置实例的返回值
更推荐的方式是利用patch自动传入的Mock参数,直接配置实例的行为,这样代码更清晰,也不需要提前创建Mock:
import unittest from unittest.mock import patch import dummy_objects as do @patch("dummy_objects.DummyObject") class TestCaseOne(unittest.TestCase): def test_patching_foo(self, mock_dummy_class): # mock_dummy_class是被替换的DummyObject类的Mock # mock_dummy_class.return_value 就是调用DummyObject()得到的实例 mock_dummy_class.return_value.foo.return_value = "9999" tmp = do.DummyObject() self.assertEqual(tmp.foo(), "9999") # 测试通过
为什么原来的代码会失败?
再理一遍流程帮你理解:
- 你用
patch把dummy_objects.DummyObject替换成了dummy_patch这个Mock。 - 当你执行
tmp = do.DummyObject()时,本质是调用dummy_patch(),也就是Mock的__call__方法。 - Mock的
__call__默认会生成一个新的Mock实例并返回,这个新实例和你之前配置的dummy_patch没有关系。 - 所以
tmp.foo()调用的是这个新Mock的foo方法,而它没有被设置返回值,自然返回默认的MagicMock对象。
内容的提问来源于stack exchange,提问作者JonnyOhneha
相关产品推荐
相关产品推荐

