MongoEngine подключается к неверной базе данных во время тестирования - PullRequest
0 голосов
/ 03 июня 2019

Context

Я создаю Flask приложение, подключенное к mongodb с использованием MongoEngine через расширение flask-mongoengine .Я создаю свое приложение, используя application factory pattern, как указано в конфигурации инструкции.

Проблема

Во время выполнения тестов я указал базу данных тестирования с именем datazilla_test, котораяпередано в mongo экземпляр через mongo.init_app(app).Даже если мой экземпляр app.config['MONGODB_DB'] и mongo.app.config['MONGODB_DB'] имеет правильное значение (datazilla_test), это значение не отражается в экземпляре mongo.Таким образом, когда я запускаю утверждение assert mongo.get_db().name == mongo.app.config['MONGODB_DB'], эта ошибка срабатывает AssertionError: assert 'datazzilla' == 'datazzilla_test'

Вопрос

Что я делаю не так?Почему соединение с базой данных сохраняется с базой данных по умолчанию datazzilla, а не datazilla_test?Как это исправить?

Исходный код

# __init__.py
from flask_mongoengine import MongoEngine

mongo = MongoEngine()


def create_app(config=None):
    app = Flask(__name__)

    app.config['MONGODB_HOST'] = 'localhost'
    app.config['MONGODB_PORT'] = '27017'
    app.config['MONGODB_DB'] = 'datazzilla'

    # override default config
    if config is not None:
        app.config.from_mapping(config)

    mongo.init_app(app)

    return app
# conftest.py
import pytest
from app import mongo
from app import create_app


@pytest.fixture
def app():
    app = create_app({
        'MONGODB_DB': 'datazzilla_test',
    })

    assert mongo.get_db().name == mongo.app.config['MONGODB_DB']
    # AssertionError: assert 'datazzilla' == 'datazzilla_test'

    return app

Ответы [ 2 ]

1 голос
/ 04 июня 2019

Mongoengine уже подключен, когда вызывается ваше устройство, когда вы вызываете app = create_app из своего устройства, оно пытается восстановить соединение, но молча терпит неудачу (поскольку видит, что установлено существующее соединение по умолчанию).

Это переработано в версии mongoengine для разработки (см. https://github.com/MongoEngine/mongoengine/pull/2038), но еще не выпущено (по состоянию на 04 июня 2019 г.). Когда эта версия выйдет, вы сможете отключитьсялюбое существующее соединение mongoengine, позвонив по номеру disconnect_all

. Тем временем вы можете: - проверить, где создано существующее соединение и предотвратить его; - попытаться отключить существующее соединение, используя следующую команду:

from mongoengine.connection import disconnect, _connection_settings

@pytest.fixture
def app():
    disconnect()
    del _connection_settings['default']
    app = create_app(...)
    ...

Но у него могут быть и другие побочные эффекты

0 голосов
/ 06 июня 2019

Контекст

По совпадению, я разобрался с этой проблемой. @bagerard ответ правильный! Это работает для MongoClient, где клиентское соединение установлено на True - это / должно быть значением по умолчанию.

MongoClient(host=['mongo:27017'], document_class=dict, tz_aware=False, connect=False, read_preference=Primary())

Если это так, то вам нужно disconnect database and delete connection settings, как объясняет @bagerard.

Решение

Однако, если вы измените MongoClient соединение на False, вам не нужно будет отключать базу данных и удалять настройки соединения . Конечным решением, которое работало для меня, было это решение.

def create_app(config=None):
    ...
    app.config['MONGODB_CONNECT'] = False
    ...

Примечания

Как я писал ранее. Я нашел это решение случайно, я пытался решить эту проблему MongoClient открылся до форка. Создавайте MongoClient только после разветвления . Оказалось, что это решает обе проблемы :)

P.S. Если есть какие-либо побочные эффекты, я не знаю их на данный момент! Если вы найдете что-то, пожалуйста, поделитесь ими в разделе комментариев

...