pythondjangounit-testingdjango-rest-frameworkdjango-rest-framework-simplejwt

How to write a unit test on Django REST API endpoint that has permission_classes = (IsAuthenticated,)


Hello everyone I'm looking to write unit test on my django app, in order to test the different API endpoint but it seems like i can't figure our the problem here is a snap code of what i have done so far :

urls.py :

path('translate/display/', DisplayTranslation.as_view(), name='display_translation'),

it's corresponding DRF view.py :

class DisplayTranslation(generics.ListAPIView):
    queryset = Translation.objects.all()
    serializer_class = TranslationSerializers
    permission_classes = (IsAuthenticated,)

and here is what I have done so far on my unit test.py :

apiclient = APIClient()

class TranslationTestCases(APITestCase):
    def setUp(self):
        self.role = baker.make(Roles)
        self.user = baker.make(Users, user_role=self.role)
        self.token = reverse('token_obtain_pair', kwargs={'email': self.user.email, 'password': self.user.password})
        self.translation = baker.make(Translation, _quantity=10)
    
    def test_get_all_translations(self):
        header = {'HTTP_AUTHORIZATION': 'Token {}'.format(self.token)} 
        response = self.client.get(reverse('display_translation'), {}, **header)
        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 10)

This is the error I'm getting when I run the test : in _reverse_with_prefix raise NoReverseMatch(msg) django.urls.exceptions.NoReverseMatch: Reverse for 'token_obtain_pair' with keyword arguments '{'email': 'dZbQNWCjif@example.com', 'password': 'PfQzPqqVVLAdLZtJyVUxVjkGJEgRABYdHxMRhCGZJWxnZxpxEgUkgUKklENrWlBiYOCxhaDtJXdtXCtNdOJYtSWTzIrdvPnrmezXBNjEYYTpyZWjOLMnMIBMAfYnLwcC'}' not found. 1 pattern(s) tried: ['token/$']

Some more info, in the authentication on my Django app, I worked with DRF, rest_auth & SimpleJWT library.

What I could do to improve my code? or an alternative solution? I couldn't find a similar problem to mine.


Solution

  • You can basically use

    @patch.object(DisplayTranslation, "permission_classes", [])
    def test_get_all_translations(self):
        ...
    

    https://docs.python.org/3/library/unittest.mock.html#patch-object

    With Authentication:

    urlpatterns = [
        ...
        path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
        path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
        ...
    ]
    
    class TranslationTestCases(APITestCase):
        def setUp(self):
            self.api_client = APIClient()
            self.role = baker.make(Roles)
            self.user = baker.make(Users, user_role=self.role)
            self.token_url = reverse('token_obtain_pair')
            self.translation = baker.make(Translation, _quantity=10)
            response = self.api_client.post(self.token_url, {"username": self.user.username, "password": self.user.password})
            self.token = response.json()["access"]
        
        def test_get_all_translations(self):
            header = {'HTTP_AUTHORIZATION': 'Bearer {}'.format(self.token)} 
            ...
    
    

    https://django-rest-framework-simplejwt.readthedocs.io/en/latest/getting_started.html