【问题标题】:Django - testing view which works with ajax requestsDjango - 测试与 ajax 请求一起使用的视图
【发布时间】:2013-06-04 12:55:38
【问题描述】:

我想测试我的视图在处理后是否返回正确的 json。这是我的看法:

@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')

这可以正常工作。这是我尝试过的测试:

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 返回空字符串。

谢谢。

【问题讨论】:

  • 我不明白你的第二个断言。 response.content 肯定会类似于 {"new_title": 2} 吗?
  • @DanielRoseman 可能。但它返回空字符串 ''
  • 为什么你的视图返回302?你好像没有发出一个?
  • @dm03514 我不知道。在我看来,这不是唯一一个返回 302。
  • 我在测试这个视图时没有登录。这可能会导致 302 状态码吗? @dm03514

标签: django django-unittest


【解决方案1】:

如果您使用 django.test 模块对其进行测试。

Django 在请求对象上有一个非常方便的函数,可以确定请求是否是 AJAX 请求(XMLHttpRequest):

request.is_ajax()

它只是检查 X-REQUESTED_WITH 标头是否等于“XMLHttpRequest”,这是大多数 javascript 库都支持的标准。

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

请注意 is_ajax 在 Django 3.1 中已被弃用,并将在以后的版本中从 Django 中删除。

【讨论】:

  • 请注意,X-Requested-With在使用XMLHttpRequest或fetch时默认浏览器不会添加标头,这是像JQuery这样的客户端库添加的。
【解决方案2】:

看起来您的 login_required 装饰器正在重定向您未经身份验证的用户。确保创建一个测试用户并使用测试客户端login 方法登录该用户

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

【讨论】:

    【解决方案3】:

    当响应代码为 302 时,您正在处理重定向。重定向有自己的对象分配给它们,它们的 .content 属性是空的。如果你想跟随重定向,你可以在client.post中添加follow=True,如果你想检查重定向位置,你可以检查response[“Location”]。

    【讨论】:

      【解决方案4】:

      您现在可以执行以下操作:

      client.post("http://example.com", {"foo": "bar"}, xhr=True)
      

      【讨论】:

        猜你喜欢
        • 2016-06-18
        • 2017-09-16
        • 2015-02-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-03
        相关资源
        最近更新 更多