如何在pytest中Mock整个导入模块(替换util为mocking_util)
如何在测试中Mock整个Python模块以替代原模块?
我拥有以下文件:
- main.py
- util.py
- mocking_util.py
- test_main.py
希望在测试代码中使用mocking_util.py替代util.py。已知可以用mocker.patch("util.my_something1", return_value=1)来Mock单个函数,但这仅适用于函数级别,请问如何Mock整个模块?
各文件代码如下:
main.py
# 修正原代码的导入错误:去掉.py后缀,同时修正函数名拼写 from . import util def something1(a, b): return util.my_something1(a, b) def something2(a, b): return util.my_something2(a, b) def something3(a, b): return util.my_something3(a, b)
util.py
def my_something1(a, b): return a + b def my_something2(a, b): return a + b + 1 def my_something3(a, b): return a + b + 2
mocking_util.py
# 修正原代码的重复定义错误,改为my_something3 def my_something1(a, b): return 1 def my_something2(a, b): return 1 def my_something3(a, b): return 1
解决方案
你可以直接用mocker.patch替换main模块中导入的util对象,将其替换为mocking_util模块。具体实现如下:
修改后的test_main.py代码:
import main import mocking_util # 导入mock模块 def test_case1(mocker): # 直接替换main模块中的util引用为mocking_util mocker.patch("main.util", new=mocking_util) result = main.something1(10, 10) assert result == 1 result = main.something2(10, 10) assert result == 1 result = main.something3(10, 10) assert result == 1
原理说明
因为main.py中通过from . import util导入的是模块对象,main.util直接指向原util模块。我们通过patch这个引用,将其替换为mocking_util模块后,main中所有调用util.xxx的地方都会自动使用mocking_util里的对应函数,无需逐个Mock单个函数。
如果你的项目是包结构(包含__init__.py),确保导入路径与项目结构匹配即可。
内容的提问来源于stack exchange,提问作者HG K
相关产品推荐
相关产品推荐

