I am trying to properly unit test my Flask 1.1.2
routes, but do not really understand the documentation around mocking the application context.
Here is my class Launch.py
:
from flask import Flask, request
from LaunchHelper import runController
#Create app
app = Flask(__name__)
@app.route('/write-database',methods=['POST'])
def writeDatabase():
return runController(request)
Here is my new TestLaunch.py
after following the comment of @Felipe Emirem:
import unittest
from mock import patch, MagicMock
from flask import request #added
from Launch import app #added
class TestLaunch(unittest.TestCase):
@patch('Launch.runController')
def test_writeDatabase(self,runController):
resp = MagicMock()
runController.return_value = resp
with app.test_client() as c:
ret = c.post('/write-database')
#assert ret == resp
runController.assert_called_with(request)
if __name__ == '__main__':
unittest.main()
I can now assert that runController
was called with flask.request
by importing the app
directly from Launch.py
, which makes sense. But I am not sure how to confirm that the response is returning correctly.
Additionally I am now getting the following error:
ERROR in app: Exception on /write-database [POST]
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1953, in full_dispatch_request
return self.finalize_request(rv)
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 1968, in finalize_request
response = self.make_response(rv)
File "C:\ProgramData\Anaconda3\lib\site-packages\flask\app.py", line 2117, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "C:\ProgramData\Anaconda3\lib\site-packages\werkzeug\wrappers\base_response.py", line 269, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "C:\ProgramData\Anaconda3\lib\site-packages\werkzeug\wrappers\base_response.py", line 26, in _run_wsgi_app
return app_iter, response[0], Headers(response[1])
IndexError: list index out of range
Even though the test is passing.
*Edit: Here is my old test class TestLaunch.py
before I changed to use app.test_context()
:
import unittest
from mock import patch, MagicMock
from Launch import writeDatabase
class TestLaunch(unittest.TestCase):
@patch('Launch.runController')
@patch('Launch.request')
def test_writeDatabase(self,request,runController):
resp = MagicMock()
runController.return_value = resp
ret = writeDatabase()
assert ret == resp
runController.assert_called_with(request)
if __name__ == '__main__':
unittest.main()
I ran this on older versions of flask, and it worked fine, but now I am getting Working out of request context
error due to the @patch('Launch.request')
line. I have tried to read through other stackoverflow posts and the flask documentation, but I can't really find anything that applies to my current use case.
Ok, I figured it out. Just needed to use the test_request_context
which I read about here: link .
Here is my new TestLaunch.py
:
import unittest
from mock import patch, MagicMock
from flask import request
from Launch import app, writeDatabase
class TestLaunch(unittest.TestCase):
@patch('Launch.runController')
def test_writeDatabase(self,runController):
resp = MagicMock()
runController.return_value = resp
with app.test_request_context() as c:
ret = writeDatabase()
assert ret == resp
runController.assert_called_with(request)
if __name__ == '__main__':
unittest.main()
I am not testing the URL (which I wasn't originally anyway), but I am able to test that the flask request
object is being handled properly.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.