4

I want to test that my view returns correct json after processes. here is my view:

@login_required
@require_POST
def xxx_view(request):
    if 'post_id' in request.POST:
        post_id = request.POST['post_id']

        post = Post.objects.get(id=post_id)
        post.order = 2
        post.save()

        json_dump = simplejson.dumps({'new_title': post.order,})
        return HttpResponse(json_dump, mimetype='application/json')
    else:
        return HttpResponse('oups')

this works correctly. Here is what i ve tried for testing:

from django.test import TestCase
from django.test.client import Client
from django.utils import simplejson
from app.models import *

c = Client()
class CustomTests(TestCase):
    def test_xxx(self):
        json_data = simplejson.dumps({'post_id': 1,})

        response = client.post('/content/vote/', json_data,
                content_type='application/json',
                HTTP_X_REQUESTED_WITH='XMLHttpRequest')
        self.assertEqual(response.status_code, 302) # this is OK.
        self.assertEqual(response.content, 2) # but this fails.

response.content returns empty string.

Thank you.

alioguzhan
  • 7,657
  • 10
  • 46
  • 67

4 Answers4

6

If you are testing it using django.test module.

Django has a really handy function on the request object that will determine if the request was an AJAX request (an XMLHttpRequest):

request.is_ajax()

It simply checks whether the X-REQUESTED_WITH header is equal to 'XMLHttpRequest', a standard that's supported by most javascript libraries.

from django.test.client import Client
client = Client()
client.post("http://example.com", {"foo": "bar"}, **{'HTTP_X_REQUESTED_WITH': 
'XMLHttpRequest'})

Please note that is_ajax is deprecated in Django 3.1, and will be removed from Django at a later version.

Flimm
  • 136,138
  • 45
  • 251
  • 267
Amanpreet
  • 219
  • 3
  • 10
  • Note that the `X-Requested-With` header is not added by default by the browser when using `XMLHttpRequest` or `fetch`, it's something that client-side libraries like JQuery add. – Flimm Oct 23 '20 at 13:09
3

It looks like your login_required decorator is redirecting your unauthenticated user. Make sure you create a test user and log that user in using test client login method

https://docs.djangoproject.com/en/dev/topics/testing/overview/#django.test.client.Client.login

dm03514
  • 54,664
  • 18
  • 108
  • 145
3

When the response code is 302 you are dealing with a redirect. Redirects have their own object assigned to them, and their .content property is empty. If you want to follow the redirect you can add follow=True to the client.post, if you want to check the redirect location you can check response["Location"].

Emil Stenström
  • 13,329
  • 8
  • 53
  • 75
0

You can now do the following:

client.post("http://example.com", {"foo": "bar"}, xhr=True)
Mick
  • 30,759
  • 16
  • 111
  • 130