1

I'm new to testing in DRF. I have the following ViewSet where I'm only allowing the 'List' and 'Retrieve' actions:

class RecipeViewSet(mixins.ListModelMixin,
                    mixins.RetrieveModelMixin,
                    viewsets.GenericViewSet):

    permission_classes = [permissions.AllowAny]
    queryset = Recipe.objects.filter(visible=True).order_by('-created')
    pagination_class = RecipeListPagination
    lookup_url_kwarg = 'recipe_id'

    def get_serializer_class(self):
        if self.action == 'list':
            return RecipeListSerializer
        elif self.action == 'retrieve':
            return RecipeDetailSerializer

These are the tests I've written so far:

class RecipeViewSetTestCase(test.APITestCase):
    def setUp(self):
        # Create objects
        self.category = RecipeCategory.objects.create(name="meals")
        Recipe.objects.create(name="Pepperoni Pizza", category=self.category, description="It's rounded")
        Recipe.objects.create(name="Beef Ragu", category=self.category, description="It's moo'")

        # Get urls
        self.recipe = Recipe.objects.first()
        self.list_url = reverse('recipes-list')
        self.detail_url = reverse('recipes-detail', kwargs={'recipe_id': self.recipe.id})

    def test_recipe_list(self):
        response = self.client.get(self.list_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(len(response.data['results']), 2)

    def test_recipe_detail(self):
        response = self.client.get(self.detail_url)
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data['name'], self.recipe.name)

    def test_recipe_create_not_allowed(self):
        response = self.client.post(self.list_url)
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_recipe_delete_not_allowed(self):
        response = self.client.delete(self.detail_url)
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_recipe_update_not_allowed(self):
        response = self.client.put(self.detail_url)
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_recipe_partial_update_not_allowed(self):
        response = self.client.patch(self.detail_url)
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

I'm not sure if it's necessary to write a test for each method that shouldn't be allowed, or if there is a better way.

Also, I'm not sure of what else I should be testing inside this viewset.

Does anyone with experience in testing DRF knows how to properly test viewsets?

Many thanks!

Alvaro Bataller
  • 487
  • 8
  • 29
  • This looks fine, but if you want to test only viewset use `RequestFactory` instead of `Client`, and you can test permissions, authentication, pagination, even number of queries – Hari Jan 18 '21 at 12:39

0 Answers0