代码之家  ›  专栏  ›  技术社区  ›  Europa

Python flask unittest给出AttributeError:类型对象“Main”没有属性“app_context”

  •  0
  • Europa  · 技术社区  · 4 年前

    我已经制作了一个使用Python Flask提供JSON的脚本。

    JSON的URL为 localhost:3000 我也可以获得所有的日子,每天通过ID或每天按月。

    • 所有天数: http://127.0.0.1:3000/api/v1/resources/today/all
    • 今日ID: http://127.0.0.1:3000/api/v1/resources/today?id=2
    • 今天(按月份和日期): http://127.0.0.1:3000/api/v1/resources/today?month=05&day=05

    我想为脚本创建单元测试。然而,我的单元测试给了我一个 错误:

    Error
    Traceback (most recent call last):
      File "C:\Users\s\PycharmProjects\TodayPython\tests\test.py", line 8, in setUp
        self.ctx = Main.app_context()
    AttributeError: type object 'Main' has no attribute 'app_context'
    
    
    Ran 1 test in 0.009s
    
    FAILED (errors=1)
    

    Main.py:

    import datetime
    import flask
    from flask import jsonify, request, app
    
    
    class Main:
        app = flask.Flask(__name__)  # Creates the Flask application object
        app.config["DEBUG"] = True
    
        # Readme
        dt = datetime.datetime.today()
        print("All days: http://127.0.0.1:3000/api/v1/resources/today/all")
        print("Today by ID: http://127.0.0.1:3000/api/v1/resources/today?id=2")
        print("Today by month and day: http://127.0.0.1:3000/api/v1/resources/today?month=" + '{:02d}'.format(
            dt.month) + "&day=" + '{:02d}'.format(dt.day))
    
        def __init__(self):
    
            # Test data for our catalog in the form of a list of dictionaries.
            # Jokes from here: https://www.rd.com/list/short-jokes/
            self.todays = [
                {'id': 0,
                 'month': '05',
                 'day': '04',
                 'historic_event': '1670 – A royal charter granted the Hudsons Bay Company a monopoly in the fur trade in Ruperts Land (present-day Canada).',
                 'joke': 'What’s the best thing about Switzerland? I don’t know, but the flag is a big plus.'},
                {'id': 1,
                 'month': '05',
                 'day': '05',
                 'historic_event': '2010 – Mass protests in Greece erupt in response to austerity measures imposed by the government as a result of the Greek government-debt crisis.',
                 'joke': 'I invented a new word! Plagiarism!'},
                {'id': 2,
                 'month': '05',
                 'day': '06',
                 'historic_event': '2002– Founding of SpaceX.',
                 'joke': 'Did you hear about the mathematician who’s afraid of negative numbers? He’ll stop at nothing to avoid them.'},
            ]
    
            @self.app.route('/', methods=['GET'])
            def __home():
                return self.home()
    
            @self.app.route('/api/v1/resources/today/all', methods=['GET'])
            def __api_all():
                return self.api_all()
    
            @self.app.route('/api/v1/resources/today', methods=['GET'])
            def __api_id():
                return self.api_id()
    
            self.app.run(host="localhost", port=3000, debug=True)
    
        @staticmethod
        def home():
            return '''<h1>Today</h1>
            <p>A prototype API for finding out what happened on this day</p>'''
    
        def api_all(self):
            return jsonify(self.todays)
    
        def api_id(self):
    
            # Create an empty list for our results
            results = []
    
            # Check if an ID was provided as part of the URL.
            # If ID is provided, assign it to a variable.
            # If no ID is provided, display an error in the browser.
            if 'id' in request.args:
                id = int(request.args['id'])
    
                # Loop through the data and match results that fit the requested ID.
                # IDs are unique, but other fields might return many results
                for today in self.todays:
                    if today['id'] == id:
                        results.append(today)
            else:
                # Month and day search
                if 'month' in request.args and 'day' in request.args:
                    month = str(request.args['month'])
                    day = str(request.args['day'])
    
                    for today in self.todays:
                        if today['month'] == month and today['day'] == day:
                            results.append(today)
    
                    result_length = len(results)
                    if result_length == 0:
                        return "Error: Not yet implemented or not found"
                else:
                    return "Error: No id, month or day field provided. Please specify."
    
    
    
            # Use the jsonify function from Flask to convert our list of
            # Python dictionaries to the JSON format.
            return jsonify(results)
    
    
    Main();
    

    tests/test.py:

    import unittest
    
    from Main import Main
    
    
    class Test(unittest.TestCase):
        def setUp(self):
            self.ctx = Main.app_context()
            self.ctx.push()
            self.client = Main.test_client()
    
        def tearDown(self):
            self.ctx.pop()
    
        def test_home(self):
            response = self.client.get("/", data={"content": "hello world"})
            self.assertEqual(response.status_code, 200)
            self.assertEqual("POST method called", response.get_data(as_text=True))
    
    
    if __name__ == "__main__":
        unittest.main()
    
    0 回复  |  直到 4 年前
        1
  •  1
  •   wikwoj    4 年前

    你的Main类没有属性 app_context 根据 pytest for flask 烧瓶对象确实具有此属性。

    所以你应该这样做 Main.app.app_context() 而不是 Main.app_context()