【问题标题】:in a Flask unit-test, how can I mock objects on the request-global `g` object?在 Flask 单元测试中,如何模拟请求全局“g”对象上的对象?
【发布时间】:2012-12-17 09:03:47
【问题描述】:

我有一个烧瓶应用程序,它在before_filter 中建立数据库连接,与this 非常相似:

@app.before_request
def before_request():
    g.db = connect_db()

现在:我正在编写一些单元测试,但我确实希望它们进入数据库。我想用一个可以设置期望的模拟对象替换g.db

我的测试使用app.test_client(),正如烧瓶文档here 中所展示的那样。示例测试类似于

def test(self):
    response = app.test_client().post('/endpoint', data={..})
    self.assertEqual(response.status_code, 200)
    ...

测试工作并通过,但它们正在访问数据库,正如我所说,我想用模拟对象替换 db 访问。我在 test_client 中看不到任何访问 g 对象或更改 before_filters 的方法。

【问题讨论】:

    标签: python unit-testing mocking flask werkzeug


    【解决方案1】:

    这行得通

    test_app.py

    from flask import Flask, g
    
    app = Flask(__name__)
    
    def connect_db():
        print 'I ended up inside the actual function'
        return object()
    
    @app.before_request
    def before_request():
        g.db = connect_db()
    
    
    @app.route('/')
    def root():
        return 'Hello, World'
    

    test.py

    from mock import patch
    import unittest
    
    from test_app import app
    
    
    def not_a_db_hit():
        print 'I did not hit the db'
    
    class FlaskTest(unittest.TestCase):
    
        @patch('test_app.connect_db')
        def test_root(self, mock_connect_db):
            mock_connect_db.side_effect = not_a_db_hit
            response = app.test_client().get('/')
            self.assertEqual(response.status_code, 200)
    
    if __name__ == '__main__':
        unittest.main()
    

    所以这将打印出“我没有命中数据库”,而不是“我最终进入了实际函数”。显然,您需要根据实际用例调整模拟。

    【讨论】:

    • 试试这个(我不得不把它改成 'flask_module.g.connect_db')得到一个RuntimeError: working outside of request context
    • 我刚刚写了一个更完整的例子,我已经实际测试过并且可以工作。
    • 我喜欢这个主意!我唯一不明白的部分是g = G(),为什么要这样做?
    • 我认为你只是误解了这个例子。当我发布答案时,我喜欢实际运行它们。全局“g”对象无关紧要,因为它没有被修补。相反,被修补的函数是connect_db。在随机拒绝接受的答案之前,您可能想先玩一下 mock 和 patch 库。
    • 回想起来,我看不出我是如何误解这一点的。不幸的是,我的投票现在被锁定了。对不起。
    猜你喜欢
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 2013-12-21
    • 2018-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-22
    相关资源
    最近更新 更多