如何在 pytest 单元测试中使用 PropertyMock return 请求响应属性?
How do I use PropertyMock to return requests response attributes in a pytest unit test?
我正在使用 pytest-mock wrapper 和 pytest。
我无法让 PropertyMock 使用 requests package。
这是我尝试进行单元测试的函数示例:
def get():
url = f'http://foo.bar/'
response = requests.get(url)
if response.status_code != 200:
sys.exit(1)
return response.text
这是我的单元测试尝试:
import pytest
import my_module
import requests
def test_get(mocker, monkeypatch):
response_mock = mocker.MagicMock()
status_code_mock = mocker.PropertyMock(return_value=200)
text_mock = mocker.PropertyMock(return_value='xyz')
type(response_mock).status_code = status_code_mock
type(response_mock).text = text_mock
monkeypatch.setattr(requests, 'get', response_mock)
my_module.get()
测试失败,因为 response.status_code
没有返回 200。
我尝试在 requests.get()
调用之后放置一个 PDB 断点,并在 PDB 中自己检查了 response.status_code 属性。我得到一个 MagicMock 对象:
(Pdb) response.status_code
<MagicMock name='mock().status_code' id='4487925656'>
这是分配给 response
变量的 requests.get
调用的 return 值 。
这一行:
monkeypatch.setattr(requests, 'get', response_mock)
您用模拟替换了 get 方法本身。但是您可能想要的是将其替换为 returns 您在调用时响应模拟的内容,例如:
monkeypatch.setattr(requests, 'get', lambda url: response_mock)
顺便说一句,请考虑为此代码使用现有的 pytest plugins/fixtures。 requests_mock
and responses
都是不错的选择。例如,在 pip install requests_mock
之后,您的测试可能如下所示:
def test_get_better(requests_mock):
requests_mock.get("http://foo.bar/", text="xyz")
response_text = my_module.get()
assert response_text == "xyz"
我正在使用 pytest-mock wrapper 和 pytest。
我无法让 PropertyMock 使用 requests package。
这是我尝试进行单元测试的函数示例:
def get():
url = f'http://foo.bar/'
response = requests.get(url)
if response.status_code != 200:
sys.exit(1)
return response.text
这是我的单元测试尝试:
import pytest
import my_module
import requests
def test_get(mocker, monkeypatch):
response_mock = mocker.MagicMock()
status_code_mock = mocker.PropertyMock(return_value=200)
text_mock = mocker.PropertyMock(return_value='xyz')
type(response_mock).status_code = status_code_mock
type(response_mock).text = text_mock
monkeypatch.setattr(requests, 'get', response_mock)
my_module.get()
测试失败,因为 response.status_code
没有返回 200。
我尝试在 requests.get()
调用之后放置一个 PDB 断点,并在 PDB 中自己检查了 response.status_code 属性。我得到一个 MagicMock 对象:
(Pdb) response.status_code
<MagicMock name='mock().status_code' id='4487925656'>
这是分配给 response
变量的 requests.get
调用的 return 值 。
这一行:
monkeypatch.setattr(requests, 'get', response_mock)
您用模拟替换了 get 方法本身。但是您可能想要的是将其替换为 returns 您在调用时响应模拟的内容,例如:
monkeypatch.setattr(requests, 'get', lambda url: response_mock)
顺便说一句,请考虑为此代码使用现有的 pytest plugins/fixtures。 requests_mock
and responses
都是不错的选择。例如,在 pip install requests_mock
之后,您的测试可能如下所示:
def test_get_better(requests_mock):
requests_mock.get("http://foo.bar/", text="xyz")
response_text = my_module.get()
assert response_text == "xyz"