Search code examples
djangodjango-rest-frameworkdjango-testingdjango-tests

TestCase writing for Django authenticated API View


I have successfully written a TestCase and it's working fine.

At first have a look at my code:

Below is my tests.py

from django.shortcuts import reverse
from rest_framework.test import APITestCase
from ng.models import Contact


class TestNoteApi(APITestCase):
    def setUp(self):
        # create movie
        self.contact = Contact(userId=254, name="The Space Between Us", phone=2017, email='[email protected]')
        self.contact.save()

    def test_movie_creation(self):
        response = self.client.post(reverse('getAndPost'), {
            'userId': 253,
            'name': 'Bee Movie',
            'phone': 2007,
            'email': '[email protected]'
        })
        self.assertEqual(Contact.objects.count(), 2)

The above snippet is working fine, but the problem is... once I implement the DRF authentication system, the test fails.

Below is my settings.py:

REST_FRAMEWORK = {
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    )
}

The @permission_classes decorator with AllowAny works nicely, but if I change the value to IsAuthenticated the test fails.

I want the test to run nicely even with the IsAuthenticated value in the @permission_classes decorator.

Can anyone suggest how I can do it? I am not understanding what to change or what add in my tests.py file.


Solution

  • You should create user object in setUp method, and use client.login() or force_authenticate() to make authenticated request:

    class TestNoteApi(APITestCase):
        def setUp(self):
            # create user
            self.user = User.objects.create(username="test", password="test") 
            # create movie
            self.contact = Contact(userId=254, name="The Space Between Us", phone=2017, email='[email protected]')
            self.contact.save()
    
        def test_movie_creation(self):
            # authenticate client before request 
            self.client.login(username='test', password='test')
            # or 
            self.clint.force_authenticate(user=self.user)
            response = self.client.post(reverse('getAndPost'), {
                'userId': 253,
                'name': 'Bee Movie',
                'phone': 2007,
                'email': '[email protected]'
            })
            self.assertEqual(Contact.objects.count(), 2)