[英]How to handle view throwing manual exception in django in unit-testing?
[英]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.