如何在Flask-restful中对Resource类内部的函数进行单元测试?

问题描述 投票:-1回答:1

我对单元测试非常陌生,对于RESTful API开发也相对较新。我想知道如何在flask restful的Resource类中对功能进行单元测试?我可以对端点的响应进行单元测试,但是我不知道如何对端点的控制器类中的各个功能进行测试。

下面是我的应用程序代码。它有3个文件,包括测试:

  • app.py
  • controller.py
  • test.py
# app.py

from flask import Flask
from flask_restful import Api

from .controller import Controller


def create_app(config=None):
    app = Flask(__name__)
    app.config['ENV'] ='development'
    return app

application = app = create_app()
api = Api(app)

api.add_resource(Controller, '/ctrl')

if __name__ == "__main__":
    app.run(debug=True)
# controller.py

from flask_restful import Resource
from flask import request

class Controller(Resource):
    """
    basically flask-restful's Resource method is a wrapper for flask's MethodView
    """
    def post(self):
        request_data = self.handle_request()
        response = self.process_request(request_data)
        return response

    def handle_request(self):
        json = request.get_json()
        return json

    def process_request(data):
         # do some stuffs here
         return {'foo': 'bar'}

我正在使用unittest

# test.py

import unittest

from api import create_app
from .controller import Controller

# initiating class to try testing but I don't know how to start
controller = Controller()

class ControllerTestCase(unittest.TestCase):
    def setUp(self):
        self.app = create_app()
        self.app.config['TESTING'] = True
        self.client = app.test_client()
        self.payload = {'its': 'empty'}

    def tearDown(self):
        pass

    def test_get_response(self):
        response = self.client.post('/controller', json=self.payload)
        expected_resp = {
            'foo': 'bar'
        }
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.get_json(), expected_resp)

if __name__ == "__main__":
    unittest.main()

我想知道如何正确地对handle_requestprocess_request功能进行单元测试

python flask flask-restful
1个回答
0
投票

您的代码中有几个错误,因此不容易解释。

首先,建议使用Flask(和Flask-Restful)进行测试的方法是使用PyTest而不是unittest,因为它更易于设置和使用。

查看文档:Testing Flask Applications

但是,您可以从unittest开始...

note:您可能会对您的app模块和该模块中的app实例感到困惑。因此,为避免这种情况,我导入了模块。另一个好的做法是将测试模块与测试模块相对应:“ app.py” =>“ test_app.py”。您也可能对controller模块和controller实例感到困惑。最佳做法是使用更精确的名称,例如“ controller_foo”或其他名称…

这里是工作单元测试:

# test_app.py

import unittest

import app


class ControllerTestCase(unittest.TestCase):
    def setUp(self):
        self.app = app.app
        self.app.config['TESTING'] = True
        self.client = self.app.test_client()
        self.payload = {'its': 'empty'}

    def test_get_response(self):
        response = self.client.post('/ctrl', json=self.payload)
        expected_resp = {'foo': 'bar'}
        self.assertEqual(response.status_code, 200)
        self.assertDictEqual(response.get_json(), expected_resp)


if __name__ == "__main__":
    unittest.main()

如您所见,我还修复了发布的URL,在您的应用程序中,URL是“ / ctrl”,而不是“ controller”。

此时,测试可以运行,但是您还有另一个错误:

Ran 1 test in 0.006s

FAILED (errors=1)

Error
Traceback (most recent call last):
  ...
TypeError: process_request() takes 1 positional argument but 2 were given

如果您查看process_request()方法,您会发现您错过了self参数。像这样更改它。

    def process_request(self, data):
        # do some stuffs here
        return {'foo': 'bar'}

您的考试应该通过。

但是,这不是实施Flask-Restful控件的正确方法。阅读doc并使用getpost方法…

© www.soinside.com 2019 - 2024. All rights reserved.