testingjwtdjango-ninja

Testing API with ninja_jwt


Im trying to play around with Django to learn it. At the moment i created a App which pasted together from different Tutorials. Im using Django Ninja extra, and the recommended JWT Token. And i try to make some automated Test for my small API. To Access the API Calls i need the JWT Token, so i thought i could call it in the Setup method, because it will be needed for every API Call. I cant seem to figure out how to call from Ninja JWT to obtain the token.

My Testcase:

from django.test import TestCase, Client
from ninja_extra.testing import TestClient
from ninja_jwt.controller import NinjaJWTDefaultController
from .api import MyAPIController
# Create your tests here.
class DepartmentTest(TestCase):
    token: str
    
    def setUp(self) -> None:
        self.client = TeWTstClient(MyAPIController)
        tokenClient = TestClient(NinjaJWTDefaultController)
        login = { "password": "testPassword",
                  "username": "test"
                }
        responseAuth = tokenClient.post("api/token/pair", data=login)
        self.token = responseAuth.data["refresh"]

    def test_create_Department(self):
        # Arragne
        department = { "title": "TestTitel" }

        # Act
        response = self.client.post("/department", data=department, headers={ "Authorization": 'Bearer' + self.token})

        # Assert
        self.assertEqual(response.status_code, 200)

When i try to run the Test:

Found 1 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: test_create_Department (company.tests.DepartmentTest.test_create_Department)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/user/VSWorkspace/playground/company/tests.py", line 15, in setUp
    responseAuth = tokenClient.post("token/pair", data=login)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/VSWorkspace/playground/.venv/lib/python3.12/site-packages/ninja/testing/client.py", line 49, in post
    return self.request("POST", path, data, json, **request_params)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/user/VSWorkspace/playground/.venv/lib/python3.12/site-packages/ninja_extra/testing/client.py", line 40, in request
    func, request, kwargs = self._resolve(
                            ^^^^^^^^^^^^^^
  File "/home/user/VSWorkspace/playground/.venv/lib/python3.12/site-packages/ninja/testing/client.py", line 119, in _resolve
    raise Exception(f'Cannot resolve "{path}"')
Exception: Cannot resolve "token/pair"

----------------------------------------------------------------------
Ran 1 test in 0.003s

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


Solution

  • So i found out what my Problem was(There were Multiple things) following code is working properly:

    from django.test import TestCase, Client
    from ninja_extra.testing import TestClient
    from ninja_jwt.controller import NinjaJWTDefaultController
    from .api import MyAPIController
    import json
    from django.contrib.auth.models import User
    
    # Create your tests here.
    class DepartmentTest(TestCase):    
        def setUp(self) -> None:
            self.client = TestClient(MyAPIController)
            
    
        def test_create_Department(self):
            # Arragne
            department = { "title": "TestTitel" }
            tokenClient = Client(NinjaJWTDefaultController)
            login = { "password": "testPassword",
                      "username": "testuser"
                    }
            
            self.user = User.objects.create_user(username='testuser', password='testPassword')
    
            responseAuth = tokenClient.post("/api/token/pair", data=json.dumps(login), content_type="application/json")
            token = json.loads(responseAuth.content.decode('UTF-8'))
            
            # Act
            response = self.client.post("/department", json.dumps(department), headers={ "Authorization": 'Bearer ' + str(token["access"])})
    
            # Assert
            self.assertEqual(response.status_code, 200)
    

    But i didnt yet figure out how to put the token part in the setUp