[As per https://stackoverflow.com/a/46369945/1021819, the title should refer to integration tests rather than unit tests]
Suppose I'd like to test the following Flask API (from here):
import flask
import flask_restful
app = flask.Flask(__name__)
api = flask_restful.Api(app)
class HelloWorld(flask_restful.Resource):
def get(self):
return {'hello': 'world'}
api.add_resource(HelloWorld, '/')
if __name__ == "__main__":
app.run(debug=True)
Having saved this as flaskapi.py
and run it, in the same directory I run the script test_flaskapi.py
:
import unittest
import flaskapi
import requests
class TestFlaskApiUsingRequests(unittest.TestCase):
def test_hello_world(self):
response = requests.get('http://localhost:5000')
self.assertEqual(response.json(), {'hello': 'world'})
class TestFlaskApi(unittest.TestCase):
def setUp(self):
self.app = flaskapi.app.test_client()
def test_hello_world(self):
response = self.app.get('/')
if __name__ == "__main__":
unittest.main()
Both the tests pass, but for the second test (defined in the TestFlaskApi
) class I haven't yet figured out how to assert that the JSON response is as expected (namely, {'hello': 'world'}
). This is because it is an instance of flask.wrappers.Response
(which is probably essentially a Werkzeug Response object (cf. http://werkzeug.pocoo.org/docs/0.11/wrappers/)), and I haven't been able to find an equivalent of the json()
method for requests
Response object.
How can I make assertions on the JSON content of the second response
?
With Python3, I got the error
TypeError: the JSON object must be str, not bytes
. It is required to decode:This question gives an explanation.
I've found that I can get the JSON data by applying
json.loads()
to the output of theget_data()
method:Both tests pass as desired:
Flask provides a test_client you can use in your tests:
Flask Testing Docs
What you're doing there is not unit testing. In every case, when using the requests library or the flask client, you're doing integration testing as you make actual http calls to the endpoints and test the interaction.
Either the title of the question or the approach is not accurate.