[Django]-Django REST Framework: TestCase is not returning correct queryset

4๐Ÿ‘

โœ…

I suspect, (without having your product model at hand) that you are not getting all the elements from the products table, for the following reasons:

  • You created your first 9 elements manually, without registering them to a specific user.
  • Afterward, you added an authentication method (TokenAuthentication) and create some users with access tokens.
  • Because you added an authentication method, you probably added @permission_classes((IsAuthenticated,)) / permission_classes=(IsAuthenticated,) to your product-list view.
    That restricts any unauthenticated user from accessing the product-list.
    The unauthenticated-anonymous users will only see the anonymous elements of your database.
  • You added the next 2 elements and the comment with one of the registered users, which in turn registered those elements to the user-creator, therefore you cannot access them without an authenticated user.

To access resources that need authentication from the DRFโ€™s test client, you need to authenticate your user first.
You can use force_authenticate method:

class TestInventoryList(APITestCase):
    def setUp(self):
        self.req_factory = APIRequestFactory()
        self.view =  views.InventoryList.as_view({'get': 'list',})

    @pytest.mark.django_db
    def test_get_product_list(self):
        url = reverse('product-list')
        request = self.client.get(url)
        force_authenticate(request, user=YOUR_USER)
        response = self.view(request)
        print(response.json())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.json()), 11)

This test assumes that you list method returns Products.objects.all()


As @cezar points out, testing a view against real data is prone to fail (for example, when you add a new element, the self.assertEqual(len(response.json()), 11) will fail)

You should consider mocking your responses to create an isolated environment.

I tend to use a combination of factory_boy and django-nose (pytest works as well).

๐Ÿ‘คJohn Moutafis

Leave a comment