You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 20:20:17