pythondjangounit-testingendpointkeyerror

Django APIView returns “IndexError: list index out of range” in unit test but works in Postman


I have written an APIView in Django that returns a random line from a database table. When I test it using Postman, I get the response I want. However, when I call the URL of the endpoint in a unit test, I get an “IndexError: list index out of range” error.

Here’s my code:

Endpoint

def get(self, request, **kwargs):
        all_the_pickup_id = PickupData.objects.values_list('id', flat=True)
        # if not all_the_pickup_id:
        #     return Response("No pickup lines found.")
        random_id = random.choice(all_the_pickup_id)
        random_pickup = PickupData.objects.get(id=random_id)
        random_line = random_pickup.text
        return Response(random_line)

Unit Test Code

def test_text_response(self):
        client = APIClient()
        response = client.get('/getPickup/getUnitTest/')
        self.assertEqual(response['Content-Type'], 'application/json')
        print('Get Pickup',response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)

How can I fix this error and make my unit test work?


Solution

  • The issue is occuring because most likely the all_the_pickup_id list is empty. When running unit tests, django creates a test database (separate from your actual database) that is empty. You need to first populate it with some values so that your test works.

    Modify your test function like this:

    def test_text_response(self):
        # create some pick up data
        PickupData.objects.create(**data) # data is a dictionary representing your fields
        PickupData.objects.create(**data2)
        client = APIClient()
        response = client.get('/getPickup/getUnitTest/')
        self.assertEqual(response['Content-Type'], 'application/json')
        print('Get Pickup',response.content)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
    

    Or even better create the data in the setUp method, so you can reuse it across test functions.