Test cases are always referring to default database in case of Multiple databases

24 views
Skip to first unread message

vai...@ebex.com.au

unread,
Jun 8, 2016, 6:49:31 AM6/8/16
to Django users
Hi,
I am trying to run some test cases on one of the apps of my Django Project.
My settings.py file specifies two different databases as follows:

        DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        },
        'guest': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.guest.sqlite3'),
        }
    }


My models are as follows:

    class Industry(AbstractTimestampClass):
        name = models.CharField(max_length=100, unique=True)

        def __str__(self):
            return self.name

        def __unicode__(self):
            return self.name

        class Meta:
            verbose_name_plural = "Industries"



    class Aim(AbstractTimestampClass):
        name = models.CharField(max_length=100, unique=True)
        icon = models.CharField(max_length=255)

        def __str__(self):
            return self.name

        def __unicode__(self):
            return self.name


    class Campaign(AbstractTimestampClass):
        website = models.CharField(max_length=255)
        industry = models.ManyToManyField(Industry,       related_name='related_industry_guest_campaigns')
        aim = models.ManyToManyField(Aim, related_name='related_aim_guest_campaigns')
        tracking_id = models.CharField(max_length=50, null=True, blank=True, db_index=True)
    
        def save(self, *args, **kwargs):
            '''add custom events while saving category'''
            if self.id is None:
                self.tracking_id = str(uuid.uuid4())
            super(Campaign, self).save(*args, **kwargs)

        def __str__(self):
        return str(self.id)

        def __unicode__(self):
            return str(self.id)

My serializer is as follows:

    class GuestCampaignSerializer(serializers.ModelSerializer):
        class Meta:
            model = Campaign
            fields = ('website', 'tracking_id', 'industry', 'aim',    'created_on')

        def validate(self, data):
            if data['website']:
                parsed_url = urlparse(data['website'])
                data['website'] = parsed_url.scheme + '://' +  parsed_url.netloc
        return data

        def create(self, validated_data):
            try:
                campaign =     Campaign.objects.using('guest').create(website=validated_data['website'])
                campaign.save(using='guest')
                campaign.aim.clear()
                campaign.aim.set(validated_data['aim'],using='guest')
                campaign.industry.clear()
                campaign.industry.set(validated_data['industry'],using='guest')
                return campaign
            except Exception as e:
                print "Exception in GuestCampaignSerializer - " + str(e)


The view is as follows:

    class GuestCampaignViewSet(APIView):
        permission_classes = (permissions.AllowAny,)
        serializer = GuestCampaignSerializer

        def post(self, request):
            '''
                Create new guest variation
                ---
                type:
                    website:
                        required: true
                        type: string

                responseMessages:
                    -   code: 200
                        message: 
                    -   code: 400
                        message: Bad request
            
                consumes:
                    - application/json

                produces:
                    - application/json
            '''
            try: 
                print "In Guest campaign create"
                print Industry.objects.using('guest').all()
                data = self.serializer(data=request.data)
                if data.is_valid():
                    campaign_obj = data.save()

                    # save first page w.r.t newly created campaign info
                    page_obj = Page()
                    page_obj.url = request.data['website']
                    page_obj.campaign_id = campaign_obj.id
                    page_obj.save(using='guest')

                    return Response({
                        "campaign" : {
                            "tracking_id": data.data['tracking_id'],
                        },
                        "page":  {
                           "id": page_obj.id,
                        },
                    }, status=status.HTTP_201_CREATED)
                else:
                    return Response({
                        "error" : {
                            "message" : "Error while creating the Guest Campaign",
                            "details" : data.errors
                        }
                    }, status=status.HTTP_400_BAD_REQUEST)

            except Exception as e:
                return Response({
                    "details": str(e)
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


The test case is as follows:
    
    class GuestCampaignViewTestcase(TestCase): 
        multi_db = True
        fixtures = ['initial.guest.json']
        def setUp(self):
            self.client = APIClient()
            self.endpoint = '/webservice/v3/guest/campaigns/'
            self.tracking_id = None
            self.campaign_data = {
                "website": "http://www.ebex.in/this-is-a-test/",
                "industry": [1, 2],
                "aim": [2,3]
            }

        def test_clean_create_guest_campaign(self):
            '''
                Use Case: Campaign create success
                Expected HTTP Code: 201
            '''
            response = self.client.post(self.endpoint, self.campaign_data,     "json")
            print response
            self.assertEqual(response.status_code, status.HTTP_201_CREATED)
            self.assertIn("campaign", response.data)
            self.assertIn("page", response.data)
            self.assertEqual(len(response.data['campaign']['tracking_id']), 36)
            self.assertIn('id', response.data['page'])


The above test case is sub-classed from django.test.TestCase

The fixture '**initial.guest.json**' creates sample Aim and Industry objects for testing as follows:

    [{"model": "guest.industry", "pk": 1, "fields": {"created_on": "2016-06-07T05:43:30.305Z", "modified_on": "2016-06-07T05:43:30.305Z", "name": "IT"}},{"model": "guest.industry", "pk": 2, "fields": {"created_on": "2016-06-07T05:43:36.275Z", "modified_on": "2016-06-07T05:43:36.275Z", "name": "Agri"}}, {"model": "guest.aim", "pk": 1, "fields": {"created_on": "2016-06-07T05:44:13.047Z", "modified_on": "2016-06-07T05:44:13.047Z", "name": "Service", "icon": "abcd"}}, {"model": "guest.aim", "pk": 2, "fields": {"created_on": "2016-06-07T05:44:23.635Z", "modified_on": "2016-06-07T05:44:23.635Z", "name": "Promotions", "icon": "abcdef"}}, {"model": "guest.aim", "pk": 3, "fields": {"created_on": "2016-06-07T05:44:33.730Z", "modified_on": "2016-06-07T05:44:33.730Z", "name": "Marketing", "icon": "abcdefg"}}]


When I run this test case using:

    python manage.py test guest.tests.GuestCampaignViewTestcase.test_clean_create_guest_campaign

I am getting this error:
    
    Exception in GuestCampaignSerializer - Cannot add "<Aim: Promotions>": instance is on database "guest", value is on database "default"
    
Actually in the test environment the Serializer is resolving the campaign aim and industry many to many keys with instances from the '**default**' database instead of the '**guest**' database.

How can I instead make it resolve these keys using the '**guest**' database.
Reply all
Reply to author
Forward
0 new messages