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

Python测试中Monkeypatch模拟方法失效,调用真实方法求助

问题分析与解决建议

核心问题1:导入方式导致Mock失效

如果你的service_class.py里是直接导入函数而非通过模块引用,比如:

# service_class.py 错误的导入方式
from repository_class import find_by_id

def get_details(id):
    # ...
    item = find_by_id(id)
    # ...

这种情况下,service_class里的find_by_id是原函数的本地引用,你通过monkeypatch修改repository_class模块的find_by_id不会影响这个本地引用,所以测试时仍会调用真实方法。

修复方式:

修改service_class.py的导入逻辑,通过模块引用函数:

# service_class.py 正确的导入方式
import repository_class

def get_details(id):
    # ...
    item = repository_class.find_by_id(id)
    # ...

核心问题2:Mock对象不是可调用类型

你的测试代码里把find_by_id替换成了字符串"abc",但原函数是可调用对象,这样在service_class.get_details调用时会抛出TypeError(尝试调用字符串)。你需要替换成可调用的Mock对象,比如用lambda或模拟函数。

修复后的测试代码:

def test_bid_on_brand_keyword(monkeypatch):
    # 定义可调用的Mock函数,返回模拟数据
    def mock_find_by_id(id):
        return "abc"

    # 替换repository_class模块中的find_by_id
    monkeypatch.setattr(repository_class, 'find_by_id', mock_find_by_id)

    ans = service_class.get_details(1)  # 传入具体的测试id值
    assert ans is not None

如果不想修改原代码的导入方式,也可以直接Mockservice_class里的本地引用:

def test_bid_on_brand_keyword(monkeypatch):
    def mock_find_by_id(id):
        return "abc"

    # 直接替换service_class中导入的find_by_id引用
    monkeypatch.setattr(service_class, 'find_by_id', mock_find_by_id)

    ans = service_class.get_details(1)
    assert ans is not None

内容的提问来源于stack exchange,提问作者Sha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:05:22