Pytest 适用于旧模拟,但不适用于 unittest.mock
Pytest works with old mock, but not unittest.mock
我正在将一些代码从 Python 2 移植到 3,并且 py.test
不能很好地与 unittest.mock
的 patch
装饰器一起使用。当我使用 patch
装饰器将模拟传递给测试函数的参数时,py.test
反而将该参数解释为固定装置,并且无法设置测试。
这里有一个人为的例子,希望能说明问题:
@patch('my_module.my_func')
def test_my_func(mock_func):
mock_func()
mock_func.assert_called_once_with()
在 运行ning py.test
之后,错误消息如下所示:
E fixture 'my_func' not found
> available fixtures: cache, capfd, capsys, doctest_namespace, monkeypatch, pytestconfig, record_xml_property, recwarn, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
这是发生此故障的唯一情况。如果我明确调用测试(即 运行 test_my_func()
),则不会出错。如果我使用其他任何一种修补技术修补 my_func
,都不会出错。如果我从 mock
而不是 unittest.mock
导入补丁,没有错误。
只有当 运行使用 py.test
、使用 unittest.mock
进行我的测试并在发生这种情况时使用装饰器进行修补。
我是 运行宁 Python 3.4.5.
是的,不支持模拟装饰器。
这还不错——通过装饰器更改函数签名被认为是个坏主意。
但是您仍然可以使用 with mock.patch(...)
语法。
还有一个选项,pytest-mock 插件非常干净 api 用于模拟:
def test_foo(mocker):
# all valid calls
mocker.patch('os.remove')
mocker.patch.object(os, 'listdir', autospec=True)
mocked_isfile = mocker.patch('os.path.isfile')
有一个 pytest
问题现在似乎已在更新版本的 pytest
中得到解决:
https://github.com/pytest-dev/pytest/pull/3206/commits/b6166dccb4d2b48173aa7e7739be52db9d2d56a0
基本上,如果您安装了 mock
,这将失败。您可以通过卸载 mock
和 运行 再次测试来验证。
如果你真的需要那个版本的 pytest,你可以在函数内部使用 with patch(..)
来获取模拟。
我正在将一些代码从 Python 2 移植到 3,并且 py.test
不能很好地与 unittest.mock
的 patch
装饰器一起使用。当我使用 patch
装饰器将模拟传递给测试函数的参数时,py.test
反而将该参数解释为固定装置,并且无法设置测试。
这里有一个人为的例子,希望能说明问题:
@patch('my_module.my_func')
def test_my_func(mock_func):
mock_func()
mock_func.assert_called_once_with()
在 运行ning py.test
之后,错误消息如下所示:
E fixture 'my_func' not found
> available fixtures: cache, capfd, capsys, doctest_namespace, monkeypatch, pytestconfig, record_xml_property, recwarn, tmpdir, tmpdir_factory
> use 'pytest --fixtures [testpath]' for help on them.
这是发生此故障的唯一情况。如果我明确调用测试(即 运行 test_my_func()
),则不会出错。如果我使用其他任何一种修补技术修补 my_func
,都不会出错。如果我从 mock
而不是 unittest.mock
导入补丁,没有错误。
只有当 运行使用 py.test
、使用 unittest.mock
进行我的测试并在发生这种情况时使用装饰器进行修补。
我是 运行宁 Python 3.4.5.
是的,不支持模拟装饰器。
这还不错——通过装饰器更改函数签名被认为是个坏主意。
但是您仍然可以使用 with mock.patch(...)
语法。
还有一个选项,pytest-mock 插件非常干净 api 用于模拟:
def test_foo(mocker):
# all valid calls
mocker.patch('os.remove')
mocker.patch.object(os, 'listdir', autospec=True)
mocked_isfile = mocker.patch('os.path.isfile')
有一个 pytest
问题现在似乎已在更新版本的 pytest
中得到解决:
https://github.com/pytest-dev/pytest/pull/3206/commits/b6166dccb4d2b48173aa7e7739be52db9d2d56a0
基本上,如果您安装了 mock
,这将失败。您可以通过卸载 mock
和 运行 再次测试来验证。
如果你真的需要那个版本的 pytest,你可以在函数内部使用 with patch(..)
来获取模拟。