我一直在尝试找到一种同时使用模拟装饰器和pytest capsys的方法,但是我找不到正确的方法来实现它。
import pytest
import requests_mock
@requests_mock.mock()
def test_with_mock(m):
pass
def test_with_capsys(capsys):
pass
# how to write a test that works with both?
答案 0 :(得分:2)
如request-mock
's docs中所述:
pytest
有其自己的注册和加载自定义装置的方法。requests-mock
提供了向pytest
注册的外部设备,因此只需将其指定为参数即可使用。无需导入requests-mock
,只需安装并指定参数requests_mock
。然后,灯具提供与
requests_mock.Mocker
相同的界面,使您可以按预期使用requests-mock
。>>> import pytest >>> import requests >>> def test_url(requests_mock): ... requests_mock.get('http://test.com', text='data') ... assert 'data' == requests.get('http://test.com').text ...
因此,只需使用requests_mock
固定装置而不是装饰器即可:
def test_with_mock_and_capsys(requests_mock, capsys):
pass
pytest
不能与将位置参数添加到测试函数的函数装饰器一起使用。 pytest
考虑所有符合条件的参数
functools.partial
绑定; unittest.mock
的模拟代替替换为fixture值,如果找不到适合任何参数的fixture,它将失败。这样的东西
import functools
import pytest
def deco(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
args += ('spam',)
return func(*args, **kwargs)
return wrapper
@deco
def test_spam(spam_arg):
assert True
将失败,而这正是requests-mock
所做的。一种解决方法是通过关键字args传递模拟程序:
import pytest
import requests_mock
@requests_mock.Mocker(kw='m')
def test_with_mock_and_fixtures(capsys, **kwargs):
m = kwargs['m']
...
但是由于requests-mock
已经提供了灯具,为什么还要麻烦使用装饰器?