Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is APITest with Query params different then just normal url?

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.

like image 458
user133688 Avatar asked May 04 '14 00:05

user133688


People also ask

What is the difference between URL parameters and query strings?

Both parameters and query string contain key-value pairs. In a POST request, parameters can appear in the URL itself, but also in the datastream (as known as content). Query string is always a part of the URL. Parameters can be buried in form-data datastream when using POST method so they may not appear in the URL.

When use query params vs URL params?

Query vs. ' in the URL, path parameters come before the question mark sign. Secondly, the query parameters are used to sort/filter resources. On the other hand, path parameters are used to identify a specific resource or resources. You can't omit values in path parameters since they are part of the URL.

Is query param part of URL?

Query parameters are a defined set of parameters attached to the end of a url. They are extensions of the URL that are used to help define specific content or actions based on the data being passed.

Can you POST with query params?

POST should not have query param. You can implement the service to honor the query param, but this is against REST spec.


1 Answers

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.

like image 140
Alex Avatar answered Sep 23 '22 08:09

Alex