12

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

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

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

我的测试正在使用,如这里app.test_client()的烧瓶文档所示。一个示例测试看起来像

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

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

4

1 回答 1

27

这有效

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()

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

于 2013-01-03T19:52:44.250 回答