在Flask单元测试中访问mongo实例

时间:2017-08-12 23:46:23

标签: python unit-testing flask

我在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实例,在整个应用程序中使用它。但是,我找不到设置一个使用'测试'的新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()。在烧瓶测试设置中实例化测试数据库的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

我不知道如何通过配置文件来做到这一点,但我还有另一种可能让你感兴趣的方法。

当我在我的flask / mongo应用程序中创建单元测试时,我只是简单地读取了sys.args(在我的' __ init __。py '中)并且从那里决定是否要使用测试DB或实际DB,如下所示:

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

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

如果您对整个设置感兴趣,请查看我的example app

答案 1 :(得分:0)

您将需要在每个需要访问配置中定义的不同数据库的不同单元测试中重新创建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)