0

I am trying to run tests on the app I am developing and I am having problems. The application uses 2 databases, an MySQL one for configuration and relational data and a MongoDB one for some other records that are not relational. It works when I'm using it normally as Y just syncdb the relational DB... but when I try to run tests, Django is trying to sync both DBs and then crashes as it gets some errors in mongo with the models. Any suggestions?

This is the configuration of the DB:

DATABASES = {
     'default': {
            'ENGINE': 'django.db.backends.mysql', 
            'NAME': 'app',
            'USER': 'test',
            'PASSWORD': 'test',
            'HOST': '127.0.0.1',
            'PORT': '3306',
     },
     'nonsql': {
            'ENGINE' : 'django_mongodb_engine',
            'NAME' : 'app',
            'HOST': '127.0.0.1',  
            'PORT': 27017,        
     },        
}

The router:

class AppRouter(object):
def db_for_read(self, model, **hints):
    if model._meta.app_label == 'nonsql':
        return 'nonsql'
    return None

def db_for_write(self, model, **hints):
    if model._meta.app_label == 'nonsql':
        return 'nonsql'
    return None

def allow_relation(self, obj1, obj2, **hints):
    if obj1._meta.app_label == 'nonsql' or \
       obj2._meta.app_label == 'nonsql':
       return True
    return None

def allow_syncdb(self, db, model):
    if db == 'auth_db':
        return model._meta.app_label == 'nonsql'
    elif model._meta.app_label == 'nonsql':
        return False
    return None

Test code:

import pymongo
from django.test import TestCase
from app import views
from app.models import Car
from bson.objectid import ObjectId
from django.test import Client
import json

class CarTest(TestCase):

    def setUp(self):
        Operation.objects.create(id = ObjectId("5396d352421aa93f63ca45d5"), name = "Test Car", description= "Test Description",
                                 start_date="2011-03-26 13:54:37.355", end_date="2014-09-11 13:54:37.355")

    def test_adding_operation(self):
        c = Client()
        response = c.post('/cars/',{"name":"Test car 002", "description":"Test description car 002", "start_date":"2014-09-05 13:54:37.355", "end_date":"2014-09-11 13:54:37.355"})
        content = json.loads(response.content)
        # we expect to receive status success and an id
        self.assertEqual("ok",content['status'])
        self.assertNotEqual("",content['result'])     
Fabiot
  • 429
  • 1
  • 4
  • 13

1 Answers1

0

OK, it seems I found a solution that works... even though I am not sure is the best approach. I have included a conditional in the settings so when the app is in test mode, it uses just MySQL database, so it doesn't duplicate the tables in both databases when it does the syncdb, and after, in the setUp method of the test I am adding the second MongoDB.

The code looks something like this:

Settings.py

import sys
if 'test' in sys.argv:
DATABASES = {
 'default': {
        'ENGINE': 'django.db.backends.mysql', 
        'NAME': 'app',
        'USER': 'test',
        'PASSWORD': 'test',
        'HOST': '127.0.0.1',
        'PORT': '3306',
 },    
}

tests.py

    def setUp(self):
    test_mongo_db = {
            'ENGINE' : 'django_mongodb_engine',
            'NAME' : 'test',
            'HOST': '127.0.0.1',  
            'PORT': 27017,        
    }
    NEW_DATABASES = settings.DATABASES
    NEW_DATABASES['nonsql'] = test_mongo_db

I hope this helps if anybody else is in the same situation.

Fabiot
  • 429
  • 1
  • 4
  • 13