Is APITest with Query params different then just normal url?

user133688 picture user133688 · May 4, 2014 · Viewed 22.2k times · Source

I'm writing some unit tests against an API that either returns all the books, or only returns the books of the given genre in the query params. This seems to be working when I hit it in my local dev server. However, it doesn't even go into the else statement if the genre is specified in my unit test.

My unit test looks like this:

class TitlesAndBlurbsListTestCase(APITestCase):
     def setUp(self):
     # Creates a lot of books with genre horror
     # and books not in the horror genre

     def test_horror_genre(self):
         # Ensure that screener can see all the available books
         self.client.login(username='b', password='b')
         response = self.client.get('/api/titles-and-blurbs/?genre=horror')
         self.assertEqual(response.status_code, status.HTTP_200_OK)

         # Ensure that the screener gets all horror books at first
         horror_books = TitlesAndBlurbs.objects.filter(genre='horror')
         # I keep getting an assertion error here - it returns all the books
         self.assertEqual(len(response.data), horror_books.count()) 

My api viewset looks like this

class TitlesAndBlurbsListViewSet(viewsets.mixins.ListModelMixin,
               viewsets.mixins.RetrieveModelMixin,
               viewsets.GenericViewSet):
    model = TitlesAndBlurbs
    permission_classes = [ScreenerPermissions]
    serializer_class = TitlesAndBlurbsSerializer

    def get_queryset(self):
        if self.action == 'list':
            genre = self.request.QUERY_PARAMS.get('genre', None)
            if not genre:
                print 'i dont have query params of genre'
                TitlesAndBlurbs.objects.all()
            else:
                print genre
                TitlesAndBlurbs.objects.filter(genre=genre)
        return TitlesAndBlurbs.objects.all()

my url/router looks like

router.register(r'api/titles-and-blurbs', TitlesAndBlurbsListViewSet)

When I hit the url 'api/titles-and-blurbs/?genre=horror' in my browser I get the print statement and titles and blurbs that have the genre horror. However, when I hit in the test suite, I don't get the print statement genre I get the print statement of 'i dont have query params', and it returns all books. Any help is really appreciated.

Answer

Alex picture Alex · May 4, 2014

Try passing the query parameter as a data payload instead. Change the line in your test to:

response = self.client.get('/api/titles-and-blurbs/', {'genre': 'horror'})

Django docs here on the different ways to pass query parameters in urls.

Another person reported a similar issue with an empty QUERY_PARAMS while testing DRF (see here). It looks like they fixed it but maybe they missed something or you didn't get the update.