简体   繁体   中英

How to use application context to mock flask request

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM