samedi 19 octobre 2019

Test cases for Django Rest Framework; struggling to get a correct response

I am writing tests for my Django Rest Framework API but I am struggling to get my code to return a 200 OK. At the moment, my test case continually returns a 404 Not Found.

I'm in the early stages of writing tests, and have a lot to learn. I'm currently following https://www.django-rest-framework.org/api-guide/testing/

I'm trying to test an endpoint at the following URL

# Not shown here, is that all URLs here will be prepended with /api/v1
    path('case/<int:pk>/', EntireCaseView.as_view(), name='case'),

I have an object in my database with an ID (primary key) of 1. I can successful query the API by going to http://localhost:8000/api/v1/case/1/

I receive a valid JSON response (Trampe is a rabbit)

{
    "id": 1,
    "total_points": 5000,
    "passing_points": 3700,
    "budget": 5000,
    "description": "Saving Trampe from Trauma",
    "name": "Trampe",
    "signalment": "8yr, intact male, mixed breed.",
    "problem": "Respiratory difficulty",
    "image": {
        "id": 1,
        "file": "http://localhost:8000/media/images/trampe.jpg",
        "description": "A lovely picture of Trampe"
    },

My API requires authentication, and as such I am providing authentication in my test case.

class CaseTests(APITestCase):

    def test_status_code(self):
        """
        ensure that case/1 returns 200 OK
        """
        # Create a test user
        test_user = User(username='jim', password='monkey123', email='jim@jim.com')
        test_user.save()

        factory = APIRequestFactory()
        user = User.objects.get(username='jim')
        view = EntireCaseView.as_view()
        url = reverse('case', kwargs={'pk': '1'})
        print(url.__str__())
        # Make an authenticated request to the view...
        request = factory.get(url)
        print(request.get_full_path())
        force_authenticate(request, user=user)
        response = view(request, "1")
        print(response.data)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

Of interest here (at least to me) are the lines url = reverse('case', kwargs={'pk': '1'}) and response = view(request, "1")

If I leave out either the kwargs argument in url =r everse('case', kwargs={'pk': '1'}) or the "1" in response = view(request, "1") I will receive an error saying that the get() method requires 2 positional arguments but only given.

Here is the signature of the get() method in my view.

class EntireCaseView(APIView):
    def get(self, request, pk):

If I run my test, Django reports that it fails because of a 404.

    self.assertEqual(response.status_code, status.HTTP_200_OK)
AssertionError: 404 != 200

What I am trying to work out is why this is the case. Printing print(url.__str__()) outputs /api/v1/case/1/ as does print(request.get_full_path())

So in summary, I am trying to understand why I'm receiving this 404, and ultimately, how I can test this, and other endpoints.

Any and all help is appreciated.

Cheers, C

Aucun commentaire:

Enregistrer un commentaire