Search code examples
pythonunit-testingflaskpytest

with pytest.raises(Exception) not working with flask app.post


i have a folder like this

python
├── foo
│   ├── __init__.py
│   └── web
│       ├── __init__.py
│       ├── api
│       │   ├── __init__.py
│       │   └── helper_api.py
│       └── server.py         
└── test_server.py
    ├── test_helper_api.py

The helper_api.py is like

@helper_api.route("/helper", methods=['POST'])
def helper():
    data = request.get_json(force=True, silent=True, cache=True)
    if data is None:
        raise QueryParseException("JSON-formatted query is required, none found")

In the test_helper_api.py, I have

import ......
from foo.web.api.helper_api import QueryParseException

class TestClass(object):
    @pytest.fixture
    def client(self, request):
        self.client = server.app.test_client()
        return self.client

    def test_helper_api(self, client):
        with pytest.raises(QueryParseException):
            client.post('/helper')

When I run the test class, the code fails at client.post, a exception was raised, however pytest failed to catch it.

    ---------------------------------------------------- Captured log call -----------------------------------------------------
app.py                    1761 ERROR    Exception on /helper [POST]
Traceback (most recent call last):
  File "/Users/...personal path.../flask/app.py", line 2292, in wsgi_app
    response = self.full_dispatch_request()
  .......
  File "/Users/...personal path.../foo-1.0.0-py3.6.egg/foo/web/api/helper_api.py", line 12, in precheck
    raise QueryParseException("JSON-formatted query is required, none found")
foo.web.api.helper_api.QueryParseException: JSON-formatted query is required, none found

why pytest is not catching this exception?


Solution

  • Flask test client is a test client used to test what will happen in the user side when you do a request to the endpoint. The reason why pytest doesn't and should not catch the exception is that the error happens on server side, user should not have a server side exception.

    Instead, to test your QueryParseException is correctly raised in server side, you can assert the status code of client.post('/helper'). Meanwhile, in server side, you can give the error message and status code to let the client know what's wrong.