我想了解如何在仅针对调用方法的测试中使用HTTPException
的同时捕获flask.abort
提出的test_request_context
的情况。
# example.py
import flask
@api.route('/', methods=['POST'])
def do_stuff():
param_a = get_param()
return jsonify(a=param_a)
# check if request is json, return http error codes otherwise
def get_param():
if flask.request.is_json():
try:
data = flask.request.get_json()
a = data('param_a')
except(ValueError):
abort(400)
else:
abort(405)
# test_example.py
from app import app # where app = Flask(__name__)
from example import get_param
import flask
def test_get_param(app):
with app.test_request_context('/', data=flask.json.dumps(good_json), content_type='application/json'):
assert a == get_param()
在上述get_param
方法中,如果abort
或is_json()
失败,我会尝试get_json()
。为了对此进行测试,我通过了一个test_request_context
而没有一个content_type
,并且基于此blog和这个answer,我尝试添加一个嵌套的上下文管理器,如下所示:
# test_example.py
from app import app # where app = Flask(__name__)
from example import get_param
from werkzeug.exceptions import HTTPException
import flask
def test_get_param_aborts(app):
with app.test_request_context('/', data=flask.json.dumps('http://example', 'nope'), content_type=''):
with pytest.raises(HTTPException) as httperror:
get_param()
assert 405 == httperror
但是我收到一个assert 405 == <ExceptionInfo for raises contextmanager>
断言错误。
有人可以解释一下,并提出一种方法来测试这种abort
方法中的get_param
吗?
更新: 根据@tmt的答案,我修改了测试。但是,即使测试通过了,但在调试时,我注意到这两个断言从未达到!
# test_example.py
from app import app # where app = Flask(__name__)
from example import get_param
from werkzeug.exceptions import HTTPException
import flask
def test_get_param_aborts(app):
with app.test_request_context('/', data=flask.json.dumps('http://example', 'nope'), content_type=''):
with pytest.raises(HTTPException) as httperror:
get_param() # <-- this line is reached
assert 405 == httperror.value.code
assert 1 ==2
答案 0 :(得分:1)
httperror
是ExceptionInfo的实例,该实例是pytest自己的描述异常的类。一旦发生,httperror
也将包含value
属性,该属性将是HTTPException
本身的实例。如果我的记忆正确,则HTTPException
包含code
属性,该属性等于HTTP状态代码,因此您可以使用它执行断言:
# test_example.py
from app import app
from example import get_param
from werkzeug.exceptions import HTTPException
import flask
def test_get_param_aborts(app):
with app.test_request_context('/', data=flask.json.dumps(), content_type=''):
with pytest.raises(HTTPException) as httperror:
get_param()
assert 405 == httperror.value.code
注释:
get_param()
需要在pytest.raises()
上下文管理器中调用。pytest.raise
是您的错别字还是pytest的较早版本中确实存在。 AFAIK应该是pytest.raises
。