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

Python单元测试patch类方法返回MagicMock而非预设值问题

问题根因

你的mock返回值设置路径写错了。@patch 替换SecretManagerConnection类之后,传入测试用例的mock_sm是类本身的mock对象,不是类实例的mock对象。
你写的mock_sm.pull_secret().return_value = "xxx",本质是给「直接通过类调用pull_secret方法」的场景设置返回值,但你的业务代码里是先实例化类:gcp_sm = SecretManagerConnection(),再调用实例的gcp_sm.pull_secret(),走的是mock类实例的方法路径,根本没命中你设置返回值的对象,所以拿到的是默认生成的MagicMock实例。

你遇到的报错信息其实已经明确提示了调用路径:AssertionError: assert <MagicMock name='SecretManagerConnection().pull_secret()' id='xxx'> == '预设的token值',这里的SecretManagerConnection()就代表实例化后的对象,说明你设置返回值时漏掉了实例化这一层的return_value。

修正方案

有两种标准写法可以解决这个问题:

方案1:显式获取实例mock后设置返回值

mock_sm.return_value 对应类实例化后得到的实例对象mock,在这个实例mock上给pull_secret方法设返回值即可:

@patch("app.utilities.utility_functions.SecretManagerConnection")
def test_fetch_token_google_secret(mock_sm):
    os.environ["GCP_PROJECT_ID"] = "test"
    # 拿到实例化后的mock对象
    mock_instance = mock_sm.return_value
    # 给实例的pull_secret方法设置返回值
    mock_instance.pull_secret.return_value = "1234567890.abcdefghijklmnopqrstuvwxyz"

    del os.environ["TOKEN"]
    assert fetch_token("test") == "1234567890.abcdefghijklmnopqrstuvwxyz"

方案2:链式调用return_value设置

unittest.mock对类mock做了属性代理,你可以直接通过链式写return_value匹配调用路径,不需要单独声明实例变量:

@patch("app.utilities.utility_functions.SecretManagerConnection")
def test_fetch_token_google_secret(mock_sm):
    os.environ["GCP_PROJECT_ID"] = "test"
    # 第一个return_value对应实例化得到的对象,第二个对应pull_secret方法的返回值
    mock_sm.return_value.pull_secret.return_value = "1234567890.abcdefghijklmnopqrstuvwxyz"

    del os.environ["TOKEN"]
    assert fetch_token("test") == "1234567890.abcdefghijklmnopqrstuvwxyz"
避坑提示
  • 你之前的错误写法对应的调用场景是SecretManagerConnection.pull_secret()(类直接绑定方法调用,不经过实例化),和业务代码的调用路径完全不匹配。
  • 测试中手动修改os.environ容易污染其他测试用例,建议用pytest的monkeypatch fixture管理环境变量,测试结束后自动回滚。

内容的提问来源于stack exchange,提问作者Dom.MB

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 01:06:29