Pytest适用于旧的mock,但不适用于unittest.mock

Jam*_*her 6 python unit-testing mocking pytest python-3.x

我正在将一些代码从Python 2移植到3,并且py.test不能很好地使用patch装饰器unittest.mock.当我使用patch装饰器将模拟传递给测试函数的参数时,py.test而是将该参数解释为fixture,并且无法设置测试.

这是一个人为的例子,希望能够解决这个问题:

@patch('my_module.my_func')
def test_my_func(mock_func):
    mock_func()
    mock_func.assert_called_once_with()
Run Code Online (Sandbox Code Playgroud)

运行后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.
Run Code Online (Sandbox Code Playgroud)

这是发生此故障的唯一方案.如果我明确调用测试(即运行test_my_func()),没有错误.如果我my_func使用其他任何一种修补技术进行修补,则没有错误.如果我输入补丁从mock代替unittest.mock,没有错误.

只有在发生这种情况时才使用装饰器运行我的测试py.test,使用unittest.mock和修补.

我正在运行Python 3.4.5.

And*_*lov 10

是的,不支持模拟装饰器.它并不是那么糟糕 - 装饰设备改变功能签名被认为是个坏主意.但你仍然可以使用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')
Run Code Online (Sandbox Code Playgroud)

  • 当您说不支持它们时,谁不支持它们呢?参见https://docs.python.org/3/library/unittest.mock.html,其中提到了修补程序作为装饰器的可用性 (2认同)