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

如何Mock类的静态工厂方法以返回Mock对象?测试问题求助

解决Toto类静态工厂方法的Mock问题

我明白你遇到的问题了——你想Mock Toto.factory() 让它返回一个Mock实例,但测试里的两个Mock对象没关联起来,导致断言失败。咱们一步步来修复这个问题:

问题根源

你的测试代码里有两个关键问题:

  1. 重复Patch导致对象不一致:你同时Patch了整个Toto类和它的factory静态方法,这会让factory返回的Mock和你设置get_name返回值的Mock不是同一个实例。
  2. Patch路径错误:你用__name__ + ".Toto.factory"来Patch工厂方法,但Toto.method_to_test()里调用的是模块junit.toto中的Toto.factory,所以Patch的路径应该对应这个实际调用的位置。

正确的测试代码

下面是修复后的测试,我会逐行解释:

from junit.toto import Toto
import pytest
from unittest.mock import Mock, patch

def test_toto_method_to_test():
    # 1. 创建一个Mock的Toto实例,设置我们需要的返回值
    mocked_toto_instance = Mock()
    mocked_toto_instance.get_name.return_value = "Tata"

    # 2. 只Patch Toto的factory静态方法,让它返回我们创建的Mock实例
    # 注意路径是实际被调用的factory方法所在的位置:junit.toto.Toto.factory
    with patch("junit.toto.Toto.factory") as mocked_factory:
        mocked_factory.return_value = mocked_toto_instance

        # 3. 调用要测试的静态方法
        Toto.method_to_test()

        # 4. 断言get_name方法被调用了
        mocked_toto_instance.get_name.assert_called_once()

为什么这样能行?

  • 我们只针对factory方法做Patch,确保Toto.method_to_test()里调用Toto.factory()时,返回的是我们预先创建好的mocked_toto_instance。
  • 所有的操作都围绕同一个Mock实例,这样断言get_name被调用时就不会出现“不是同一个对象”的问题了。

额外提示(使用pytest-mock插件)

如果你用的是pytest-mock插件(也就是你代码里的mocker fixture),代码可以更简洁:

from junit.toto import Toto

def test_toto_method_to_test(mocker):
    # 创建Mock实例并设置返回值
    mocked_toto_instance = mocker.Mock()
    mocked_toto_instance.get_name.return_value = "Tata"

    # Patch factory方法,返回这个Mock实例
    mocker.patch("junit.toto.Toto.factory", return_value=mocked_toto_instance)

    # 调用测试方法
    Toto.method_to_test()

    # 断言
    mocked_toto_instance.get_name.assert_called_once()

这样就能确保测试通过啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:15:56