我正在尝试用requests_mock
模拟一个get请求,但似乎并不能解决问题。
我的函数调用文件lookup.py
中定义的第三方API:
from botocore.vendored import requests
def get_data():
url = 'https://abc.something.com/datapackage'
url_params={
'v': 2,
'auth_apikey':'xyz'
}
resp = requests.get(url, params=url_params)
return resp.json()
我正在使用py.test
来运行测试并在测试文件中运行。我有个固定装置:
import requests_mock
import requests, pytest
from lookup import get_data
@pytest.fixture
def req_mock(request):
m = requests_mock.Mocker()
m.start()
request.addfinalizer(m.stop)
return m
def test_api_gets_data(req_mock):
sample={
'key1':123
}
lookup_url = 'https://abc.something.com/datapackage'
query_params = {
'v': 2,
'auth_apikey':'xyz'
}
req_mock.get(lookup_url, json=sample)
resp = get_data()
显然,requests_mock
无法与get
函数中的请求使用相同的会话,因此不会受到嘲笑。
有更好的方法吗?
我正在使用Python 3.6,请求2.18,请求模拟1.52和pytest 3.0.7。
答案 0 :(得分:0)
在lookup.py
个文件中,lookup_url
将raise NameError
导致名称lookup_url
未定义。
使用url
且不要忘记更改params=url_params
,因此代码将如下所示:
resp = requests.get(url, params=url_params)
答案 1 :(得分:0)
显然,您无法使用from botocore.vendored import requests
来嘲笑requests_mock
。
请改为使用unittest.mock
模拟响应。
from unittest import mock
class MockResponse:
def __init__(self, status_code, json_data=None):
self.json_data = json_data
self.status_code = status_code
def json(self):
return self.json_data
def raise_for_status(self):
if self.status_code >= 500:
raise Exception
item_not_found = {
"Response": {
"StatusCode": "ItemNotFound",
}
}
item_not_found_resp = MockResponse(200, item_not_found)
@mock.patch('botocore.vendored.requests.get', return_value=item_not_found_resp)
def test_api_returns_not_found_when_third_party_api_returns_item_not_found(mc):
resp = get(e1, c)
exp_resp = {
"statusCode": 404,
"body": json.dumps({
'error': 'no item found'
})
}
request_url = mc.call_args[0][0]
request_params = mc.call_args[1]['params']
assert lookup_url == request_url
assert query_params == request_params
assert exp_resp == resp