Код состояния отмены фляги в катинге внутри test_request_context - PullRequest
1 голос
/ 03 ноября 2019

Я хочу понять, как я могу поймать 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 и, основываясь на этом блоге и этом ответе , я попытался добавить вложенный менеджер контекста, например, так:

# 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

1 Ответ

1 голос
/ 03 ноября 2019

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.
...