python - mock.patch 在 pytest 夹具中不起作用?
问题描述
f2()
我需要在下面编写测试用例mod1
。
mod1.py:
from mod_x import X
def f1():
raise Exception('Test shouldn''t call real f1()')
def f2():
f1()
以下是导入的mod_x
.
mod_x.py
class Y:
def func2(self):
raise Exception("Shouldn't be called")
class X:
def __init__(self):
self.producer = Y()
这是测试代码test_mod1.py
。它应该修补mod1.f1
,所以f1()
不应该调用真实的。
import mod1
import pytest
from unittest import mock
@pytest.fixture()
@mock.patch('mod1.f1')
def patched_mocked(mocked_function):
x_mock = mock.Mock(mod1.X)
x_mock.producer = mock.Mock()
x_mock.producer.func2 = lambda : None
mocked_function.return_value = x_mock
return x_mock
def test_1(patched_mocked):
mod1.f2() # f2() shouldn't call the real f1() because of patching
# assert ....
def test_2(patched_mocked):
mod1.f2()
# assert ....
然而,
test_mod1.py FF [100%] ==================================================== ==================================================== ==== 失败 =============================================== ==================================================== ========== _____________________________________________________________________________________________________________ 测试_1 __________________________________________________________________________________________________________ patched_mocked_function = def test_1(patched_mocked_function): > mod1.f2() test_mod1.py:15: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ mod1.py:7: 在 f2 f1() _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 定义 f1(): > raise Exception('测试不应该调用真正的 f1()') E 例外:测试不应调用真正的 f1() mod1.py:4:异常
解决方案
您不能在夹具上使用补丁装饰器,因为在您返回夹具时模拟将被恢复。您需要确保仅在测试结束后(例如在夹具生命周期之后)恢复模拟(例如超出范围):
@pytest.fixture()
def patched_mocked():
with mock.patch('mod1.f1') as mocked_function:
x_mock = mock.Mock(mod1.X)
x_mock.producer = mock.Mock()
x_mock.producer.func2 = lambda: None
mocked_function.return_value = x_mock
yield x_mock
在这种情况下,模拟仅在返回后yield
恢复,即测试完成后。
推荐阅读
- bash - Heroku CLI:用户 [user] 是团队管理员,无法加入 app [app]
- python - Python中的类方法没有看到定义的变量
- reactjs - 搜索时缺少文本字段值
- gitlab - Gitlab + Cockpit:普罗米修斯 100% CPU 使用率
- laravel - 为什么我在 laravel 中运行测试时收到“CSRF 令牌不匹配”?
- debian - Firebird3.0 security3.fdb 每天都被损坏/编辑导致“isc_attach_database failed”
- python - 如何获取结构化数组选择的副本
- jenkins - Jenkins 到 Bamboo 迁移和运行 Groovy
- java - Android Studio“失败:构建失败并出现异常。” 错误
- r - 如何根据一个表中的两列之间的依赖关系以及 R 中另一个表的结果来过滤结果?