Search code examples
djangounit-testingdjango-rest-frameworkdjango-unittest

How to avoid an authentication error during testing drf?


During the development process, all classes were written with a variable permission_classes = [permissions.AllowAny, ]. In the file setting.py set

'DEFAULT_AUTHENTICATION_CLASSES': [
    'rest_framework_simplejwt.authentication.JWTAuthentication', 
    'rest_framework.authentication.SessionAuthentication', 
],

When writing the tests, it was not considered that user authentication is required to fulfill the request. Therefore, when the parameter [permissions.AllowAny, ] was removed the error 401 Unauthorized occurred.

old_test.py

from django.test import TestCase, Client
from django.urls import reverse
from django.db import IntegrityError

from rest_framework.test import APITestCase
from rest_framework import status

class VendorProfileUpdateViewTest(APITestCase):

    def test_check_partial_update_api(self):
        data = {"vendor_name": "UN"}
        vendor = Vendors.objects.create(vendor_name="U4", country="US", nda="2020-12-12", )
        VendorContacts.objects.create(contact_name="Mrk", phone="2373823", email="[email protected]", vendor=vendor)
        _id = vendor.vendorid
        url = reverse('vendor_update',  kwargs={'vendorid': _id})
        response = self.client.put(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        vendor = Vendors.objects.get(vendorid=_id)
        self.assertEqual(vendor.vendor_name, 'UN')

I tried to add force_authenticate() configuration in the following way:

class ContactsUpdateViewTest(APITestCase):

    def tearDown(self): 
        self.client.force_authenticate(user=None)

    def test_contact_partial_update_api(self):
        ....

But there have been no changes.


Solution

  • You need to pass the user instance to authenticate. And it's better to do the test initialization in setUp method provided by TestCase if you're testing Private endpoints.

        def setUp(self):
            self.client = APIClient()
            self.user = get_user_model().objects.create(
                username="testUser",
                password="testpass",
               // other fields
            )
            self.client.force_authenticate(self.user)