Search code examples
pythondjangodjango-rest-frameworkdjango-testing

Django REST - How to make a test case that checks that a method is not allowed?


I have the following ModelViewSet:

class OrderViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):

I would like to create four test cases:

  • Check that (partial) updating is not allowed via OrderViewSet
  • Check that listing is not allowed via OrderViewSet
  • Check that retrieving is not allowed via OrderViewSet
  • Check that deleting is not allowed via OrderViewSet

I'm facing a couple of issues. First, I'm unable to use reverse() for all of the test cases. The following test case works:

def test_disable_read_order_list(self):
    response = self.client.get(reverse('api:orders-list', kwargs={'currency': 'eur'}))
    self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED) 

When I try to use reverse to get the URL of the detail route:

reverse('api:orders-detail', kwargs={'currency': 'eur', 'pk': self.order.id})

I get:

django.urls.exceptions.NoReverseMatch: Reverse for 'orders-detail' not found. 'orders-detail' is not a valid view function or pattern name.

I have tried to hack around this by adjusting the URL that is used for the working test case:

def test_disable_read_order_detail(self):
    response = self.client.get(reverse('api:orders-list', kwargs={'currency': 'eur'}) + str(self.order.id) + '/')
    self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

but then statuscode 200 is returned for some reason.

What is the proper way to implement the unit tests I want?


Solution

  • django.urls.exceptions.NoReverseMatch: Reverse for 'orders-detail' not found. 'orders-detail' is not a valid view function or pattern name. is a consequence of how OrderViewSet is implemented.

    It's derived from mixins.CreateModelMixin and viewsets.GenericViewSet and hence enables creating orders, but nothing else (that's why test_disable_read_order_list passes).

    You should get 404 Not Found, unless OrderViewSet inherits from mixins.RetrieveModelMixin, when you try to request an order detail (say /orders/1/) and hence it's weird that you get 200 OK in test_disable_read_order_detail.