Flask 和 pytest 中带有 500 状态码的模拟响应
Mock response with 500 status code in flask and pytest
* 已编辑*
我想测试如果外部 API 将 return 500 状态代码会发生什么。
main.py
@app.route("/<a>/<b>", methods=["GET"])
def repo_info(a: str, b: str) -> Union[Response, str]:
info = some_func(a, b)
result = create_result_dict(some_func)
return Response(
response=json.dumps(result, ensure_ascii=False),
status=200,
mimetype="application/json",
@app.errorhandler(500)
def server_error(e):
logging.exception(f"An error occurred during a request: {e}.")
return Response(
response="An internal error occurred. See logs for full stacktrace.",
status=500,
)
my_module.py
def some_func(a: str, b: str) -> Dict[str, str]:
return json.loads(
(requests.get(f"https://api.github.com/repos/{a}/{b}")).text
)
我试过这段代码,但感觉像无头鸡:
from flask import Response
import pytest
import requests
from unittest.mock import patch
from requests.exceptions import HTTPError
@patch.object(my_module, "some_func")
def test_some_func(mocked):
mocked.return_value = HTTPError()
result = my_module.some_func()
with pytest.raises(HTTPError):
result == mocked
另外 HTTPError
不带参数,我如何传递信息,我想要 500 状态代码?
第一个问题是要获得 HTTPError
异常,您需要告诉 requests
使用 raise_for_status()
:
引发它
# my_module.py
import json
import requests
from typing import Dict
def some_func(a: str, b: str) -> Dict[str, str]:
result = requests.get(f"https://api.github.com/repos/{a}/{b}")
result.raise_for_status()
return json.loads(result.text)
第二个问题是,要模拟它,您只想模拟请求(设置条件以及避免对 API 进行真正的调用),否则您确实想调用 some_func()
。毕竟,那是测试它的想法。您可以按照您尝试的方式修补对象,但我建议您安装 requests-mock:
# test.py
import pytest
import requests_mock
from requests.exceptions import HTTPError
from my_module import some_func
def test_some_func():
with requests_mock.mock() as m:
m.get(requests_mock.ANY, status_code=500, text='some error')
with pytest.raises(HTTPError):
# You cannot make any assertion on the result
# because some_func raises an exception and
# wouldn't return anything
some_func(a="a", b="b")
* 已编辑*
我想测试如果外部 API 将 return 500 状态代码会发生什么。
main.py
@app.route("/<a>/<b>", methods=["GET"])
def repo_info(a: str, b: str) -> Union[Response, str]:
info = some_func(a, b)
result = create_result_dict(some_func)
return Response(
response=json.dumps(result, ensure_ascii=False),
status=200,
mimetype="application/json",
@app.errorhandler(500)
def server_error(e):
logging.exception(f"An error occurred during a request: {e}.")
return Response(
response="An internal error occurred. See logs for full stacktrace.",
status=500,
)
my_module.py
def some_func(a: str, b: str) -> Dict[str, str]:
return json.loads(
(requests.get(f"https://api.github.com/repos/{a}/{b}")).text
)
我试过这段代码,但感觉像无头鸡:
from flask import Response
import pytest
import requests
from unittest.mock import patch
from requests.exceptions import HTTPError
@patch.object(my_module, "some_func")
def test_some_func(mocked):
mocked.return_value = HTTPError()
result = my_module.some_func()
with pytest.raises(HTTPError):
result == mocked
另外 HTTPError
不带参数,我如何传递信息,我想要 500 状态代码?
第一个问题是要获得 HTTPError
异常,您需要告诉 requests
使用 raise_for_status()
:
# my_module.py
import json
import requests
from typing import Dict
def some_func(a: str, b: str) -> Dict[str, str]:
result = requests.get(f"https://api.github.com/repos/{a}/{b}")
result.raise_for_status()
return json.loads(result.text)
第二个问题是,要模拟它,您只想模拟请求(设置条件以及避免对 API 进行真正的调用),否则您确实想调用 some_func()
。毕竟,那是测试它的想法。您可以按照您尝试的方式修补对象,但我建议您安装 requests-mock:
# test.py
import pytest
import requests_mock
from requests.exceptions import HTTPError
from my_module import some_func
def test_some_func():
with requests_mock.mock() as m:
m.get(requests_mock.ANY, status_code=500, text='some error')
with pytest.raises(HTTPError):
# You cannot make any assertion on the result
# because some_func raises an exception and
# wouldn't return anything
some_func(a="a", b="b")