flask restx - pytest in not working with error handler

607 Views Asked by At

I am building API using Flask Restx. I had written a generic exception handler which will throw an error message and code in Json format.

@app.errorhandler(APIError)
def handle_invalid_usage(error):
    logger.opt(exception=True).error(error)
    response = jsonify(error.to_dict())
    response.status_code = error.status_code
    return response

I am trying to write unit test using pytest for testing error condition(Resource Not Found). My unit test does return only 500 Internal server error (response.status_code) instead of the going through the error handler and returning 404. When I test it directly using Postman it works perfect.

@pytest.fixture(scope="session")
def app():
    app = create_app()
    return app


@pytest.fixture
def client(app):
    return app.test_client()

def test_get_sequence_resource_not_found(mocker: MockerFixture, client: FlaskClient):
    mocked = mocker.patch("service.ViewSequenceService.get_sequence")
    mocked.side_effect = ResourceNotFound('Sequence id Not Present')
    response = client.get("/sequence/f15a9f6e-7a1d-4d12-99c3-fb80d4bc98a1")
    json_data = json.loads(response.data)
    assert response.status_code == 404
    assert json_data['payload']['message'] == 'Sequence id Not Present'
    assert json_data['payload']['status'] == 404
1

There are 1 best solutions below

0
gmccoy On

Was running into the same issue. It seems that for pytest to recognize it the exception has to registered with the API instead of the app.

from flask_restx import Api 

class APIError(Exception):
    status_code = 400
    content = {"error": "Bad request"}                                                                                                                                                                                                                                                                                                                                                                                                                                                                         
 

api = Api()

@api.errorhandler(APIError)
def handle_invalid_usage(exc: APIException):
    return exc.content, exc.status_code