如何为无法直接访问的Mock类实例设置return_value?
问题根源
你通过patch拿到的MockB是对B类本身的模拟对象,当代码执行b = B()时,实际是调用MockB的__call__方法,返回的MockB.return_value才是代码中实际使用的B类模拟实例。你原来直接对MockB.bar.return_value赋值,是在给类层面的bar属性设置返回值,而代码实际调用的是实例的bar方法,自然不会生效。
另外你原代码中B类的bar方法没有加实例参数self,如果不做Mock直接运行原生代码也会抛出参数不匹配的错误,后续修复代码也同步修正了这个问题。
修复方案
只需要把返回值的设置逻辑指向模拟实例的bar方法即可,有两种常用写法:
- 链式直接设置:
MockB.return_value.bar.return_value = 2 - 先提取模拟实例再设置(更便于后续做调用断言):
mock_b_instance = MockB.return_value mock_b_instance.bar.return_value = 2 # 后续可追加调用验证,比如验证bar方法被调用一次 # mock_b_instance.bar.assert_called_once()
完整可运行代码
import unittest import unittest.mock class A: def foo(self): b = B() return b.bar() class B: def bar(self): return 1 @unittest.mock.patch("__main__.B") class MyTestCase(unittest.TestCase): def test_case_1(self, MockB): # 修正后的返回值设置逻辑 MockB.return_value.bar.return_value = 2 a = A() self.assertEqual(a.foo(), 2) # 可选验证逻辑:验证B类被实例化一次、bar方法被调用一次 MockB.assert_called_once() MockB.return_value.bar.assert_called_once() if __name__ == "__main__": unittest.main()
内容的提问来源于stack exchange,提问作者quant
相关产品推荐
相关产品推荐

