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

如何用pytest测试类的方法是否作为参数传入被Mock的方法?

如何用pytest测试类的方法是否作为参数传入被Mock的方法?

先还原下你的问题场景,你有这样的业务代码:

import concurrent.futures
from PyQt5 import QtCore

class MyTask(QtCore.QObject):
    def do(self):
        ...

class Manager(QtCore.QObject):
    def __init__(self):
        super().__init__()
        self.worker_executor = concurrent.futures.ThreadPoolExecutor()

    def run_task(self):
        self.worker_executor.submit(MyTask().do)

你想用pytest+mock验证:调用manager.run_task()时,ThreadPoolExecutor.submit确实接收到了MyTask实例的do方法作为参数,但直接比较绑定方法和类函数会失败——因为你是把**绑定方法(bound method)和类原生函数(function)**做对比,二者本身就不是同一个对象,自然断言不通过。

解决方案:从绑定方法的本质入手验证

绑定方法其实是「类函数+实例」的组合体,我们可以提取它的核心属性来做精准断言,这里有三种常用的实现方式:

方法一:检查绑定方法的__func__和__self__属性

每个绑定方法都自带__func__属性(指向对应的类原生函数)和__self__属性(指向所属的实例),我们可以分别验证这两个属性:

def test_run_task_calls_submit_with_mytask_do():
    manager = Manager()
    manager.worker_executor.submit = mock.Mock()
    
    manager.run_task()
    
    submitted_callable = manager.worker_executor.submit.call_args[0][0]
    # 验证传入的是MyTask实例的do方法
    assert isinstance(submitted_callable.__self__, MyTask)
    assert submitted_callable.__func__ is MyTask.do

方法二:简化验证——检查方法名和实例类型

如果你不需要严格对应到类的原生函数,只需要确认是MyTask实例的do方法,可以直接检查方法名和实例类型:

def test_run_task_calls_submit_with_mytask_do():
    manager = Manager()
    manager.worker_executor.submit = mock.Mock()
    
    manager.run_task()
    
    submitted_callable = manager.worker_executor.submit.call_args[0][0]
    assert submitted_callable.__name__ == "do"
    assert isinstance(submitted_callable.__self__, MyTask)

方法三:提前Mock MyTask类,精准控制实例

如果想更灵活地控制MyTask的实例,也可以先Mock整个MyTask类,这样就能直接断言传入的是我们预设的Mock实例方法:

def test_run_task_calls_submit_with_mytask_do(mocker):
    # Mock MyTask类
    mock_mytask_cls = mocker.patch("__main__.MyTask")
    mock_instance = mock_mytask_cls.return_value
    
    manager = Manager()
    manager.worker_executor.submit = mock.Mock()
    
    manager.run_task()
    
    # 断言submit传入的是mock实例的do方法
    manager.worker_executor.submit.assert_called_once_with(mock_instance.do)

这几种方式都能完美解决你遇到的绑定方法和类函数不相等的问题~

备注:内容来源于stack exchange,提问作者mike rodent

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 18:54:48