I want to be able to do conditional connect() based on either I started django in testing mode or not.
in my settings.py I use mongoengine connect() method to connect to my database but the problem is that I don't want to do that if I ran manage.py test
Is there any way I can check if settings.py is being imported from tests or not, some flag maybe.
something like if not IN_TESTS: connect()
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(...)
来源:https://stackoverflow.com/questions/4774800/mongoengine-connect-in-settings-py-testing-problem