Pytest 适用于旧的模拟,但不适用于 unittest.mock [英] Pytest works with old mock, but not unittest.mock

查看:42
本文介绍了Pytest 适用于旧的模拟,但不适用于 unittest.mock的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm porting some code from Python 2 to 3, and py.test isn't playing well with the patch decorator from unittest.mock. When I use the patch decorator to pass a mock into the arguments of a test function, py.test instead interprets that argument to be a fixture, and is unable to set up the test.

这是一个人为的例子,希望能说明问题:

Here's a contrived example that hopefully illuminates the problem:

@patch('my_module.my_func')
def test_my_func(mock_func):
    mock_func()
    mock_func.assert_called_once_with()

运行py.test后,错误信息如下:

After running py.test, the error message would look like:

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 导入补丁,没有错误.

This is the only scenario under which this failure occurs. If I explicitly call the test (i.e. run test_my_func()), no error. If I patch my_func using either of the other patching techniques, no error. If I import patch from mock instead of unittest.mock, no error.

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

It's only while running my tests using py.test, using unittest.mock, and patching using the decorator when this occurs.

我正在运行 Python 3.4.5.

I'm running Python 3.4.5.

推荐答案

是的,不支持模拟装饰器.这还不错——通过装饰器设备更改函数签名被认为是个坏主意.但是你仍然可以使用 和 mock.patch(...) 语法.

Yes, mock decorators are not supported. It's not such bad -- changing function signature by decorator appliance is considered as bad idea. But you still may use with mock.patch(...) syntax.

还有一个选项是 pytest-mock 插件,带有非常干净的 api 用于模拟:

Also as an option there is pytest-mock plugin with pretty clean api for mocking:

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 适用于旧的模拟,但不适用于 unittest.mock的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆