繁体   English   中英

单元测试Django JSON View

[英]Unit testing Django JSON View

我正在尝试为一些Django json_view视图编写一些单元测试,而我在将json_string传递给视图时遇到了麻烦。 我昨天发布了一个相关的问题,关于将json字符串传递给JS的Django视图,问题是在我的JS中我只是传递json字符串,我需要传递字符串作为对象的属性,因为我如果没有这样做,则字符串被视为生成的查询字典的关键字。 我再次遇到类似的问题,除了这次它是Django View的Django单元测试。 这是我的代码的简化版本,它产生相同的结果。

class MyTestCase(TestCase):
    def setUp(self):
        self.u = User.objects.create_user('test','test','test')
        self.u.is_active = True
        self.u.save()
        self.client.login(username='test',password='test')

    def test_create_object_from_form(self):
        """Test the creation of the Instance from the form data."""
        import json
        json_string json.dumps({'resource':{'type':'book','author':'John Doe'}})
        print(json_string)
        response = self.client.post(reverse('ajax_view'),
                                    {'form':json_string},'json')
        self.assetNotContains(response,'error')

并且视图看起来像这样

@json_view
def ajax_view(request):
    """Process the incoming form data."""
    if request.method == 'POST':
        print(request.POST)
        form_data = json.loads(request.POST['form'])
        resource_data = form_data['resource']
        form = MyUserForm(resource_data)

        if form.is_valid():
        ...

以下是运行测试时两个打印语句产生的内容。 json_string是

{"resource": {"type": "book", "author": "John Doe"}}

和查询字典看起来像

<QueryDict: {u'{\'form\': \'{"resource": {"type": "book", "author": "John Doe"}}\'}': [u'']}>

我是JS和ajax的全新手,所以不要担心伤害我的骄傲,答案可能是如此接近它可能会跳起来咬我。

最后编辑

我最初声明在post调用中必须使用头HTTP_X_REQUESTED_WITH='XMLHttpRequest' ,但在测试中这当前是假的。 此标头对于csrf中间件是必需的,但在测试中禁用了csrf。 但是,我仍然相信即使中间件禁用csrf也是一个很好的做法,因为大多数javascript库在执行ajax时默认已经传递了这个头。 此外,如果另一段未禁用的代码使用is_ajax方法,则无需调试unittest数小时以确定标头丢失。

问题在于内容类型,因为当django获得的值与text/html不同时,它不会使用默认的post数据处理来格式化数据,就像在查询中一样: type=book&author=JohnDoe例如。

那么固定代码是:

response = self.client.post(reverse('ajax_view'),
                            {'form':json_string}, 
                            HTTP_X_REQUESTED_WITH='XMLHttpRequest')

这是我自己如何使用它:

post_data = { 
    "jsonrpc" : "2.0", "method": method, "params" : params, "id" : id }
return client.post('/api/json/', 
                    json.dumps(post_data), "text/json",            
                    HTTP_X_REQUESTED_WITH='XMLHttpRequest')

做一些json-rpc。 请注意,由于我传递的内容类型与默认值不同,因此我的数据将按照post请求的原样传递。

感谢@Eric_Fortin将我转到标题,但它不会使用'client.post'来解决格式错误的查询字典的问题。 一旦我使用XMLHttpRequest标头从POST更改为GET,我的查询字典就会自行解决。 这是当前的解决方案:

response = self.client.get(reverse('ajax_view'),
                           {'form':json_string},'json',
                           HTTP_X_REQUESTED_WITH='XMLHttpRequest')

这只是部分答案,因为此请求将更改服务器上的数据,并且应该是POST而不是GET。

编辑:

这是我的测试中的最终代码,用于通过POST将JSON字符串传递给我的视图:

response = self.client.post(reverse('ajax_view'),
                            {'form':json.dumps(json_dict)})

现在从视图打印显示查询字典格式正确。

<QueryDict: {u'form': [u'{"resource": {"status": "reviewed", "name": "Resource Test", "description": "Unit Test"}}']}>

我找到了答案,同时修改了我的一个同事,删除了content_type'json'修复了格式错误的查询字典。 正在测试的视图没有使用或调用'HttpRequest.is_ajax()',发送标题XMLHttpRequest'对我的问题没有影响,尽管包含标题将构成良好形式,因为这篇文章是一个ajax请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM