Hel*_*lad 25 python mocking pytest
当使用与pytest fixture集成的mock包中的patch decorator时,我遇到了一些神秘的东西.
我有两个模块
-----test folder
-------func.py
-------test_test.py
Run Code Online (Sandbox Code Playgroud)
在func.py中:
def a():
return 1
def b():
return a()
Run Code Online (Sandbox Code Playgroud)
在test_test.py中
import pytest
from func import a,b
from mock import patch,Mock
@pytest.fixture(scope="module")
def brands():
return 1
mock_b=Mock()
@patch('test_test.b',mock_b)
def test_compute_scores(brands):
a()
Run Code Online (Sandbox Code Playgroud)
似乎补丁装饰与pytest fixture不兼容.有没有人对此有所了解?Tnanks
bux*_*bux 32
使用pytest fixture时mock.patch,测试参数顺序至关重要.
如果在模拟的参数之前放置fixture参数:
from unittest import mock
@mock.patch('my.module.my.class')
def test_my_code(my_fixture, mocked_class):
Run Code Online (Sandbox Code Playgroud)
然后模拟对象将进入my_fixture并将mocked_class作为一个夹具搜索:
fixture 'mocked_class' not found
Run Code Online (Sandbox Code Playgroud)
但是,如果您颠倒顺序,将fixture参数放在最后:
from unittest import mock
@mock.patch('my.module.my.class')
def test_my_code(mocked_class, my_fixture):
Run Code Online (Sandbox Code Playgroud)
那一切都会好的.
希望这个老问题的答案会对某人有所帮助。
首先,问题不包括错误,所以我们真的不知道发生了什么。但我会尽力提供一些对我有帮助的东西。
如果你想要一个用修补对象装饰的测试,那么为了让它与 pytest 一起工作,你可以这样做:
@mock.patch('mocked.module')
def test_me(*args):
mocked_module = args[0]
Run Code Online (Sandbox Code Playgroud)
或者对于多个补丁:
@mock.patch('mocked.module1')
@mock.patch('mocked.module')
def test_me(*args):
mocked_module1, mocked_module2 = args
Run Code Online (Sandbox Code Playgroud)
pytest 正在寻找要在测试函数/方法中查找的装置的名称。提供*args参数为我们提供了查找阶段的一个很好的解决方法。因此,要包含带有补丁的固定装置,您可以这样做:
# from question
@pytest.fixture(scope="module")
def brands():
return 1
@mock.patch('mocked.module1')
def test_me(brands, *args):
mocked_module1 = args[0]
Run Code Online (Sandbox Code Playgroud)
这对我运行 python 3.6 和 pytest 3.0.6 有用。
从Python3.3开始,该mock模块已被拉unittest入库中。还有一个反向端口(用于Python的早期版本)可以作为独立库使用mock。
将这两个库组合到同一测试套件中会产生上述错误:
E fixture 'fixture_name' not found
Run Code Online (Sandbox Code Playgroud)
在测试套件的虚拟环境中,运行pip uninstall mock,并确保没有在核心unittest库旁边使用反向移植库。卸载后重新运行测试时,会看到ImportErrors。
将此导入的所有实例替换为from unittest.mock import <stuff>。
如果您要应用多个补丁,则注入它们的顺序很重要:
# from question
@pytest.fixture(scope="module")
def brands():
return 1
# notice the order
@patch('my.module.my.class1')
@patch('my.module.my.class2')
def test_list_instance_elb_tg(mocked_class2, mocked_class1, brands):
pass
Run Code Online (Sandbox Code Playgroud)