vendredi 22 juillet 2016

Create a unit test using Django's test client post method passing parameters and requesting JSON from rest_framework

I want to instantiate a django.test.client.Client() or rest_framework.test.APIClient(), POST a simple set of parameters, and request a JSON format response from a djangorestframework class-based view.

The documentation suggests I just instantiate APIClient() and post with the parameter format='json':

rest_framework.test import APIClient
apiclient = APIClient()
response = apiclient.post('/api/v1/model/1/run',
                          data=request_params, format='json')

However then my method does not receive the request parameters. Tracing this, the parameters make it as far as RequestFactory.generic, but in its call to Client.request the data is empty.

I tried the following:

  • Passing json.dumps(request_params) to the data parameter, but same response - my view doesn't see any parameters in the request (ref).

  • Using the Django Client, passing content_type='application/json', with and without json.dumps, but same response.

  • Using Django Client, setting post **extra parameter to HTTP_ACCEPT='application/json' (with and without json.dumps) - same response.

  • Initializing the Django Client with HTTP_ACCEPT='application/json' (with and without json.dumps) - same response.

  • Leaving the Accept HTTP header, post's content_type parameter, and APIClient's format parameter undefined, and adding {'format':'json'} to the request_params - which works for Client.get requests, my code sees request parameters, but rest_framework returns HTML. The JSON rendered in this HTML shows the code is working correctly (returns status 202 and a polling URL, as it should).

My code works fine accepting AJAX POST requests through the browser, and my unit tests were working fine when I was using client.get(). It is only the combination of using client.post() and needing JSON back that I cannot get working.

I extract the request values with:

if request.method == 'POST':
    form_values = ((key, value) for key, value in request.POST.items())
else:
    form_values = ((key, value) for key, value in request.GET.items())

Aucun commentaire:

Enregistrer un commentaire