在烧瓶单元测试中访问 mongo 实例



我在app/__init__.py中有一个简单的create_app函数:

from flask import Flask
from flask_bootstrap import Bootstrap
from flask_login import LoginManager
from flask_pymongo import PyMongo
from .user_management import User
from config import app_config
login_manager = LoginManager()
mongo = PyMongo()
....
def create_app(config):
app = Flask(__name__, instance_relative_config=True, static_folder='static')
login_manager.init_app(app)
login_manager.login_message = 'You must be logged in to view this page'
login_manager.login_view = 'auth.login'
Bootstrap(app)
app.config.from_object(app_config[config])
app.config.from_pyfile('config.py')
if app.testing:
mongo.init_app(app, config_prefix='MONGO2')
else:
mongo.init_app(app)
....
return app

和我的配置:

class Config():
DEBUG = False
MONGO_HOST = 'localhost'
MONGO_PORT = 27017
....

class DevelopmentConfig(Config):
DEBUG = True
DEVELOPMENT = True

class TestingConfig(Config):
TESTING = True
DEBUG = False
CSRF_ENABLED = False
MONGO2_DBNAME = 'test'
....
app_config = {
'testing': TestingConfig,
'development': DevelopmentConfig,
'production': ProductionConfig
}

在整个应用程序中,我从此文件导入 mongo 实例,并在整个应用程序中使用它。但是,我找不到在不使用应用程序上下文的情况下设置使用"test"数据库的新 mongo 实例,就像我在这里所做的那样

我的单元测试文件如下所示。

from app import create_app
import unittest
from app import mongo
class TestCase(unittest.TestCase):
def setUp(self):
app = create_app('testing')
self.app = app
def tearDown(self):
pass
def test_mongo(self):
with self.app.app_context():
assert mongo.db.name == 'test'
if __name__ == '__main__':
unittest.main()

这似乎根本不是要走的路。这也使得无法使用 app.test_client((。在烧瓶测试设置中实例化测试数据库的正确方法是什么?

我不确定如何通过配置文件做到这一点,但我有另一种您可能感兴趣的方法。

当我为我的烧瓶/mongo应用程序创建单元测试时,我只是简单地阅读sys.args(在我的"__init__.py"中(,并从那里决定是要使用测试数据库还是实际数据库,如下所示:

if "__init__.py" == sys.argv[0]:
db = LoginManager()
else:
db = TestDB()  # if running unit tests

我不知道这是使用单元测试的最强大的方法,但它肯定是超级简单的方法,并且可以完成这项工作。

如果您对整个设置感兴趣,请查看我的示例应用程序。

您需要在每个需要访问配置中定义的不同数据库的不同单元测试中重新创建 mongo 对象。以下是我是如何做到的,为了进行真正的测试,我将一个值写入数据库,并确保我可以以两种不同的方式读回它:

import uuid
from datetime import datetime
from flask_testing import TestCase
from flask_pymongo import PyMongo
from project import app
class TestMongoDev(TestCase):
def create_app(self):
app.config.from_object('project.config.DevelopmentConfig')
return app
def test_mongo_development(self):
mongo = PyMongo(app)
testval = str(uuid.uuid4())
inserted_id = mongo.db.test.insert_one({
'testedAt': datetime.now(),
'testval': testval
}).inserted_id
self.assertTrue(mongo.db.name == 'dev')
self.assertTrue(mongo.db.test.find_one({'testval': testval})['testval'] == testval)
self.assertTrue(mongo.db.test.find_one({'_id': inserted_id})['testval'] == testval)

class TestMongoTest(TestCase):
def create_app(self):
app.config.from_object('project.config.TestingConfig')
return app
def test_mongo_testing(self):
mongo = PyMongo(app)
testval = str(uuid.uuid4())
inserted_id = mongo.db.test.insert_one({
'testedAt': datetime.now(),
'testval': testval
}).inserted_id
self.assertTrue(mongo.db.name == 'test')
self.assertTrue(mongo.db.test.find_one({'testval': testval})['testval'] == testval)
self.assertTrue(mongo.db.test.find_one({'_id': inserted_id})['testval'] == testval)

class TestMongoProd(TestCase):
def create_app(self):
app.config.from_object('project.config.ProductionConfig')
return app
def test_mongo_production(self):
mongo = PyMongo(app)
testval = str(uuid.uuid4())
inserted_id = mongo.db.test.insert_one({
'testedAt': datetime.now(),
'testval': testval
}).inserted_id
self.assertTrue(mongo.db.name == 'prod')
self.assertTrue(mongo.db.test.find_one({'testval': testval})['testval'] == testval)
self.assertTrue(mongo.db.test.find_one({'_id': inserted_id})['testval'] == testval)

最新更新