Search code examples
djangodjango-rest-frameworkweb-api-testingdjango-rest-framework-simplejwt

I am trying to test a DRF based API using DRF APITestcase and facing this error {"detail":"User not found","code":"user_not_found"}'


Hi I am running test cases for DRF based API in python using APITestcases from Django-Rest-Framework. This testcase is written for testing account creation. The same works good in postman but when running in testcase I am facing this error. I am referring to the documentation DRF APi testig Documentation.

find my code below for Test.py.

from django import test
from django.conf.urls import url
from django.http import response
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient, APITestCase

from account.api import serializer
from account.models import Account


# Create your tests here.
class RegistrationTestCase(APITestCase):
    
    databases = {"default", "django_tables"}
    
    def test_create_account(self):
        # Details to create new user
        data = {
            "username": "[email protected]",
            "email": "[email protected]",
            "password": "**********",
            "confirm_password": "**********"
        }
        #url = reverse('register',current_app='account')        
        self.client = APIClient()
        self.client.credentials(HTTP_AUTHORIZATION='Bearer ***********************')
        #client.force_authenticate(user=None)
        response = self.client.post('http://127.0.0.1:8000/api/account/register',data,format='json')
        print(response.content)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

Views.py

from django.contrib.auth.models import User
from rest_framework.response import Response
from rest_framework.decorators import api_view

from .serializer import RegistrationSerializer
from rest_framework.authtoken.models import Token
from rest_framework_simplejwt.tokens import RefreshToken, AccessToken

# # this represents to accounsts app
# # To create a new account

@api_view(['POST', ])
def registration_view(request):
    if request.method == 'POST':
        serializer = RegistrationSerializer(data=request.data)
        data = {}
        if serializer.is_valid():
            account = serializer.save()
            data['response'] = "Successfully registered a new user."
            data['email'] = account.email
            data['username'] = account.username
            
            # call function to generate tokens manually 
            token_dict = get_tokens_for_user(account)
            refresh = token_dict['refresh']
            access = token_dict['access']
            data['refresh'] = refresh
            data['access'] = access
        else:
            data = serializer.errors
        return Response(data)

# Generate the referesh token manually and display when new user is created
def get_tokens_for_user(user):
    refresh = RefreshToken.for_user(user)

    return {
        'refresh': str(refresh),
        'access': str(refresh.access_token),
    }

Error Response

(env) E:\Django\cemd-api\app>py manage.py test
Creating test database for alias 'default'...
Creating test database for alias 'django_tables'...
System check identified no issues (0 silenced).
b'{"detail":"User not found","code":"user_not_found"}'
F
======================================================================
FAIL: test_create_account (account.tests.RegistrationTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "E:\Django\cemd-api\app\account\tests.py", line 29, in test_create_account
    self.assertEqual(response.status_code, status.HTTP_201_CREATED)
AssertionError: 401 != 201

----------------------------------------------------------------------
Ran 1 test in 5.072s

FAILED (failures=1)
Destroying test database for alias 'default'...
Destroying test database for alias 'django_tables'...

I also want to automate this in future as well for other URLs where it can run in specific time intervals and then record the test results separately. Please help me with any other packages as well for API testing apart from this. I am Quite new to Django Please help. Thanks in Advance!!!


Solution

  • This is most probably caused by the default authentication classes that you have for your REST_FRAMEWORK settings. Try to disable authentication classes and permission classes for your register view:

    from rest_framework.decorators import api_view, permission_classes, authentication_classes
    
    @api_view(['POST', ])
    @authentication_classes([])
    @permission_classes([])
    def register(request):
        ...