mongoengine connect() in settings.py testing problem

雨燕双飞 提交于 2019-12-03 03:56:44

I'm solving this with a custom test runner. Here is an example I based my solution off of: https://github.com/xintron/django-mongorunner/blob/master/mongorunner/testrunner.py

This has the advantage of providing a fresh database for each of your unit tests.

class MyTestRunner(DjangoTestSuiteRunner):

    mongodb_name = 'testsuite'

    def setup_databases(self, **kwargs):
        from mongoengine.connection import connect, disconnect
        disconnect()
        connect(self.mongodb_name)
        print 'Creating mongo test-database ' + self.mongodb_name
        return super(MyTestRunner, self).setup_databases(**kwargs)

    def teardown_databases(self, old_config, **kwargs):
        from mongoengine.connection import get_connection, disconnect
        connection = get_connection()
        connection.drop_database(self.mongodb_name)
        print 'Dropping mongo test-database: ' + self.mongodb_name
        disconnect()
        super(MyTestRunner, self).teardown_databases(old_config, **kwargs)

While it is possible to do that, it is easier and common practice to have 2 settings files. One possible configuration could be:

You have 2 settings files, lsettings.py that doesn't connect and settings.py that does

from lsettings import *
mongodb.connect()

So, while locally testing you can:

python manage.py test --settings=lsettings

And it doesn't connect.

tl;dr: It is easier to manage configuration differences by having multiple configuration files that import each other conditionally rather than trying to have conditional parameters within the same settings file. YMMV.

I'm not sure it's completely foolproof, but I use the fact that in a test, you will have probably started it from the command line with ./manage.py test, so 'test' is one of the command-line args. So this works:

import sys
if 'test' not in sys.argv:
    mongodb.connect()

What I do is use register_connection, and then mock the connections on test.

In the file that I define the Mongo Documents I have this:

import mongoengine
from django.conf import settings

mongoengine.register_connection(
    'default', settings.MONGOENGINE_DB, **settings.MONGOENGINE_CONNECTION)

Then in the tests I use the mock library to change the behave of connections (it would be possible too to mock one of the functions on the connection sub module like get_db) like this:

connections = patch.dict(
    mongoengine.connection._connections, {'default': None})

dbs = patch.dict(
    mongoengine.connection._dbs, {'default': {
        'your_collection': None,
        'another_collection': None,
        }})

dbs.start()
connections.start()

insert = patch.object(mongoengine.queryset.QuerySet, 'insert')
insert_mock = insert.start()

...

insert_mock.assert_called_once(...)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!