如何Mock类的静态工厂方法以返回Mock对象?测试问题求助
解决Toto类静态工厂方法的Mock问题
我明白你遇到的问题了——你想Mock Toto.factory() 让它返回一个Mock实例,但测试里的两个Mock对象没关联起来,导致断言失败。咱们一步步来修复这个问题:
问题根源
你的测试代码里有两个关键问题:
- 重复Patch导致对象不一致:你同时Patch了整个
Toto类和它的factory静态方法,这会让factory返回的Mock和你设置get_name返回值的Mock不是同一个实例。 - 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
相关产品推荐
相关产品推荐

