0

I'm attempting to write unit tests for a file that is included inside of a flask app (microservice to handle some RESTful endpoints). Some things I'm running into: All the documentation and questions I seem to find involve invoking the APIs themselves, this isn't proper I need to invoke the post function directly with a mocked fake request that I've setup as I need to test functionality.

I'm able to attempt to mock the request.json object however i'm always met with "RuntimeError: Working outside of request context".I've attempted to use test_request_context() but that leads to the same issue. Then I started diving deeper into Flask and attempting to us app.test_client() however this has it's own problems alongside of calling the endpoint directly and doesn't let me unit test my function properly, they start moving into the realm of being integration tests.

This is the function i'm attempting to test:

@api.route...
class HandleRoute(Resource):
    @authentication #<-- I want to Mock True or False response
    def post(self): #<-- I want to call directly 
          try:
              if not request.json #<-- Value I want to mock, from flask.request

How should I be going about this? I'm trying to avoid app.test_client() and other Flask related things as again, the point of these unit tests is to check my code paths as a sanity check, not just what should happen.

1 Answers1

1

You are correct in wanting to actually perform the request, and test the received response. This is the proper way and Flask already has a built-in client to make this easy.

The official documentation already includes an example of how to do this (Testing Flask Applications). If you want to have more control over the request being processed, then have a look at Manually push a context.

I believe you are looking for the following snippet (adapted from this answer):

with app.test_client() as client:
    resp = client.post('/route', {'some_key': 'some_data'})

If you want to do away with flask.test_client() you can use python-requests to stay in the python world, or even use javascript based libraries like Chakram or Frisby

Oerd
  • 2,256
  • 1
  • 21
  • 35
  • Thank you for the response, is there not a way to invoke post() directly while mocking the request? As I stated I'm hesitant to rely on going through my endpoint directly as I will need to mock responses for functions within post(). For example post() calls a handler function that has been tested, so I don't care about the content or the work it needs to do, just the output. I'll mock a 200 or 500 response from the handler. So then I'm purely testing code paths from post() and what should return given some request object. – Brandon Hawkinson Jun 24 '19 at 23:46
  • What you want to achieve needs `test_request_context`... according to http://flask.pocoo.org/docs/1.0/api/#flask.Flask.test_request_context you have to set values for your `request` within the `with` block. – Oerd Jun 25 '19 at 00:15