首页 > 解决方案 > 如何使用应用程序上下文来模拟烧瓶请求

问题描述

我正在尝试正确地对我的Flask 1.1.2路线进行单元测试,但并不真正了解有关模拟应用程序上下文的文档。

这是我的课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)

这是我TestLaunch.py在关注@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()

我现在可以断言是通过直接导入from 来runController调用的,这是有道理的。但我不确定如何确认响应是否正确返回。flask.requestappLaunch.py

此外,我现在收到以下错误:

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

即使测试通过了。

*编辑:这是我TestLaunch.py改用之前的旧测试类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()

我在旧版本的烧瓶上运行它,它运行良好,但现在Working out of request context由于@patch('Launch.request')线路而出现错误。我试图通读其他 stackoverflow 帖子和烧瓶文档,但我真的找不到任何适用于我当前用例的内容。

标签: pythonunit-testingflaskrequest

解决方案


好的,我想通了。只需要使用test_request_context我在这里读到的:链接

这是我的新的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()

我没有测试 URL(本来我也不是),但我能够测试该flask request对象是否被正确处理。


推荐阅读