单元测试Django JSON View

sna*_*e77 10 python django ajax json unit-testing

我正在尝试为一些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')
Run Code Online (Sandbox Code Playgroud)

并且视图看起来像这样

@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():
        ...
Run Code Online (Sandbox Code Playgroud)

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

{"resource": {"type": "book", "author": "John Doe"}}
Run Code Online (Sandbox Code Playgroud)

和查询字典看起来像

<QueryDict: {u'{\'form\': \'{"resource": {"type": "book", "author": "John Doe"}}\'}': [u'']}>
Run Code Online (Sandbox Code Playgroud)

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

Eri*_*tin 9

最后编辑

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

问题在于内容类型,因为当django在那里得到一个不同于的值时text/html,它不会使用默认的后期数据处理,即在查询中格式化数据:type=book&author=JohnDoe例如.

那么固定代码是:

response = self.client.post(reverse('ajax_view'),
                            {'form':json_string}, 
                            HTTP_X_REQUESTED_WITH='XMLHttpRequest')
Run Code Online (Sandbox Code Playgroud)

这是我自己如何使用它:

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')
Run Code Online (Sandbox Code Playgroud)

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