Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DRF testing: instead of JSON an OrderedDict is returned

I'm trying to implement tests for the Django Rest Framework. Most of my tests pass and setting them up went smooth, but i'm having an issue now where an assertEqual never succeeds because it keeps comparing JSON with an OrderedDict.

I have no idea where the OrderedDict comes from since DRF should only return JSON (right?).

Might it be possible that the testing environment is parsing the JSON before comparison? That would suck.

I'm doing an integrated test that only tests the data in the response of a GET request to a certain resource, I do this based on JSON fixtures. I'm not testing a specific component of the REST framework since my implementations of the components are so simple they're already tested by the tests in the DRF project.

Anyways, I hope someone can help me!

like image 768
ZvL Avatar asked Feb 25 '15 14:02

ZvL


3 Answers

As explained here, this is because the default format for requests during tests is multipart instead of json. You can specify the format by providing it to your api call like so:

response = self.client.get('/something/1', format='json') 

Or you can set the default test request format in your settings.py like so:

REST_FRAMEWORK = {     'TEST_REQUEST_DEFAULT_FORMAT': 'json',  # Use application/json instead of multipart/form-data requests in tests. } 

To fix it for all your tests automagically.

like image 193
Allard Stijnman Avatar answered Oct 03 '22 01:10

Allard Stijnman


It sounds like you're using response.data (which returns the parsed json objects) instead of response.content (which gives the raw json string).

See http://www.django-rest-framework.org/api-guide/testing/#testing-responses

like image 21
Norgg Avatar answered Oct 03 '22 00:10

Norgg


If your tests look something like this:

class SomeTests(APITestCase):
    def test_something(self):
        response = self.client.get('/something/1')
        # assertions with response

Then response will certainly be an OrderedDict rather than a JSON document. Luckily Django 1.9 has introduced the response.json() method (https://docs.djangoproject.com/en/1.9/topics/testing/tools/#django.test.Response.json) so you can easily convert the response into JSON. Note that you could also use python's json library.

The catch here is that Django's test client (that DRF extends) is a "dummy browser" (https://docs.djangoproject.com/en/1.9/topics/testing/tools/#the-test-client) and doesn't work exactly like an in-browser framework such as Selenium would. Thus, HTTP calls are actually just simulated HTTP calls that focus on testing your logic and that correct routing/views/serializers/etc. are being used.

like image 35
elnygren Avatar answered Oct 03 '22 00:10

elnygren