python - 在 Flask 单元测试中,如何模拟请求全局 `g` 对象上的对象?

标签 python unit-testing mocking flask werkzeug

我有一个 Flask 应用程序,它在 before_filter 中设置数据库连接,非常类似于 this :

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

现在:我正在编写一些单元测试,我希望它们访问数据库。我想将 g.db 替换为我可以设置期望值的模拟对象。

我的测试使用的是 app.test_client(),正如 flask 文档中所展示的那样 here .示例测试看起来像

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

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

最佳答案

这行得通

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'

测试.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()

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

关于python - 在 Flask 单元测试中,如何模拟请求全局 `g` 对象上的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14131494/

相关文章:

flutter - 在 Flutter 上模拟 getExternalStorageDirectory

python - Windows 无法正确读取 .py 文件

python - 如何在其元类的 __init__ 方法期间将方法绑定(bind)到类?

java - 在 Android 代码中模拟创建 AsyncTasks 和 Intents 的优雅方法

ruby-on-rails - 使用Mocha模拟/ stub Application Controller方法(使用Shoulda,Rails 3)

c# - Nsubstitute,改变被替代的属性的值

python - 为什么 list(set(a+b)) 返回有序列表?它总是返回一个有序列表吗?

python - 返回其类实例的静态方法

javascript - 如何在backbone.js中为事件编写单元测试

node.js - "Cannot read property ' 数据 ' of undefined"错误 whem 使用 axios 和 moxios 进行单元测试 redux 操作