Python Unittest:如何Mock foo类构造并自定义get_name返回值?
解决方案
可以通过Python标准库unittest.mock的patch工具,针对b.py中导入的foo类或其get_name方法进行Mock,无需直接注入实例对象,具体有两种常用实现方式:
方式一:Mock foo类的get_name方法
直接替换foo类的get_name方法,让它返回自定义值:
import unittest from unittest.mock import patch from b import get_foo class TestGetFoo(unittest.TestCase): @patch('b.foo.get_name') def test_get_foo_with_mocked_get_name(self, mock_get_name): # 设置自定义返回值 mock_get_name.return_value = "MockedAlex" result = get_foo() # 断言结果符合预期 self.assertEqual(result, "MockedAlex") # 验证get_name被调用过一次 mock_get_name.assert_called_once()
方式二:Mock整个foo类,指定实例方法返回值
如果需要更灵活地控制foo实例的行为,可以Mock整个foo类,再配置其返回实例的get_name方法:
import unittest from unittest.mock import patch from b import get_foo class TestGetFoo(unittest.TestCase): @patch('b.foo') def test_get_foo_with_mocked_foo(self, mock_foo): # 配置mock实例的get_name返回值 mock_instance = mock_foo.return_value mock_instance.get_name.return_value = "MockedAlex" result = get_foo() self.assertEqual(result, "MockedAlex") # 验证foo类被使用"Alex"参数实例化过一次 mock_foo.assert_called_once_with("Alex") # 验证get_name被调用过一次 mock_instance.get_name.assert_called_once()
关键说明
- 之所以要patch
b.foo而非a.foo,是因为b.py中通过from a import foo将foo类导入到了自身模块命名空间,测试时需要针对b模块内的引用进行Mock,才能覆盖get_foo里创建实例的逻辑。 - 两种方式都能实现无需注入实例的需求,方式一更轻量,方式二更适合需要验证实例化参数或多个方法行为的场景。
内容的提问来源于stack exchange,提问作者harryk
相关产品推荐
相关产品推荐

