如何在Python中使用unittest.mock替换被测类中的对象
用mock替换MyClient测试MyClass的send方法
在Python中,你可以用标准库unittest.mock里的patch工具实现类似Java @MockBean的依赖替换,核心是替换MyClass模块中对MyClient的引用,从而注入可控制的模拟实例。
核心思路
MyClass在my_class.py中导入了MyClient并在__init__中实例化,因此需要patch的是**my_class.MyClient**(MyClass所在模块里的MyClient引用),而非原my_client.MyClient类。这样当MyClass创建实例时,会使用你预设的模拟对象代替真实的MyClient。
完整测试示例
下面是两种常用的实现方式,都能满足你的需求:
方式1:预先创建Mock实例并设置属性
import unittest from unittest.mock import patch, Mock from my_class import MyClass class TestMyClass(unittest.TestCase): def test_send_when_client_connected(self): # 创建模拟的MyClient实例,设置connected为True mock_client = Mock() mock_client.connected = True # 替换my_class模块中的MyClient,让它返回我们的模拟实例 with patch('my_class.MyClient', return_value=mock_client): my_instance = MyClass() # 捕获print输出,验证send方法的行为 with patch('builtins.print') as mock_print: my_instance.send() # 断言打印了"Sending message" mock_print.assert_called_once_with("Sending message") def test_send_when_client_disconnected(self): mock_client = Mock() mock_client.connected = False with patch('my_class.MyClient', return_value=mock_client): my_instance = MyClass() with patch('builtins.print') as mock_print: my_instance.send() # 断言没有触发打印 mock_print.assert_not_called()
方式2:通过patch返回的Mock类配置实例属性
这种方式更简洁,直接通过patch返回的模拟类来配置其实例的属性:
import unittest from unittest.mock import patch from my_class import MyClass class TestMyClass(unittest.TestCase): def test_send_with_patched_client(self): # 替换my_class.MyClient with patch('my_class.MyClient') as mock_client_class: # 获取模拟类的实例(即MyClass初始化时会得到的对象) mock_client = mock_client_class.return_value # 设置connected属性为True mock_client.connected = True my_instance = MyClass() with patch('builtins.print') as mock_print: my_instance.send() mock_print.assert_called_once_with("Sending message")
关键说明
- patch路径的选择:一定要用
my_class.MyClient,因为MyClass是从自身模块的导入中获取MyClient的,patch这个引用才能让MyClass使用模拟对象。 - 模拟属性的控制:通过给Mock实例设置
connected属性,你可以自由控制MyClass方法执行的分支,从而测试不同场景下的逻辑。 - 行为验证:用
patch('builtins.print')捕获打印操作,是为了验证send方法是否按预期执行了对应的逻辑,你也可以根据需求调整验证方式(比如断言返回值、其他方法调用等)。
内容的提问来源于stack exchange,提问作者Oeg Bizz
相关产品推荐
相关产品推荐

