我正在将一些代码从Python 2移植到3,并且py.test
与patch
的{{1}}装饰器不兼容。当我使用unittest.mock
装饰器将模拟传递给测试函数的参数时,patch
会将该参数解释为一个装置,并且无法设置测试。
这是一个人为的例子,希望能够解决这个问题:
py.test
运行@patch('my_module.my_func')
def test_my_func(mock_func):
mock_func()
mock_func.assert_called_once_with()
后,错误消息如下所示:
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
,并在发生这种情况时使用装饰器进行修补。
我正在运行Python 3.4.5。
答案 0 :(得分:8)
是的,不支持模拟装饰器。
它并不是那么糟糕 - 装饰设备改变功能签名被认为是个坏主意。
但您仍然可以使用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')
答案 1 :(得分:0)
有一个pytest
问题,现在似乎可以在pytest
的较新版本中解决:
https://github.com/pytest-dev/pytest/pull/3206/commits/b6166dccb4d2b48173aa7e7739be52db9d2d56a0
基本上,如果您安装了mock
,这将失败。您可以通过卸载mock
并再次运行测试来进行验证。
如果您确实需要该版本的pytest,则可以在函数内使用with patch(..)
来获得模拟。