单元测试视图时Django assertJSONEqual出错

时间:2015-12-07 22:58:47

标签: django unit-testing

this question类似,我在使用Django的单元测试框架测试视图时遇到问题。我的观点非常简单:它处理表单,向数据库添加对象,并返回JSONResponse。测试同样简单,但我不断得到“第一个参数是无效的JSON:''。代码实际上在我的应用程序中工作;它在单元测试时似乎不起作用。感谢任何帮助。

编辑: 回溯

======================================================================

错误:tearDownClass(zoning_intake.tests.AddActionTypeTest)

追踪(最近一次通话):   文件“C:\ Virtual \ Django18 \ lib \ site-packages \ django \ test \ testcases.py”,第96行 2,在tearDownClass中     cls._rollback_atomics(cls.cls_atomics) AttributeError:类型对象'AddActionTypeTest'没有属性'cls_atomics'

=============================================== ======================= 失败:test_post_add_action_type_succeeds(zoning_intake.tests.AddActionTypeTest)

追踪(最近一次通话):   在test_post_add_action_t中的第26行文件“C:\ Hg \ sdcgis \ zoning_intake \ tests.py” ype_succeeds     self.assertJSONEqual(response.content,{'result':'Success','msg':'Success'})

文件“C:\ Virtual \ Django18 \ lib \ site-packages \ django \ test \ testcases.py”,第68行 9,在assertJSONEqual中     self.fail(“第一个参数无效JSON:%r”%raw) AssertionError:第一个参数无效JSON:''

在10.757s中进行1次测试

失败(失败= 1,错误= 1) 为别名'default'保留测试数据库... 保留别名'other'的测试数据库......

我的观点:

    form = ActionTypeForm(request.POST)
    if form.is_valid():
        action = form.cleaned_data['action']
        new_type = CaseRequestActionType(action=action)
        new_type.save()

        return JsonResponse({'result':'Success', 'msg':'Success'})
    else:
        return JsonResponse({'result':'Fail', 'msg':'An unknown error occurred'})

我的测试:

class AddActionTypeTest(TestCase):

    if django.VERSION[:2] >= (1, 7):
        # Django 1.7 requires an explicit setup() when running tests in PTVS
        @classmethod
        def setUpClass(cls):
            django.setup()

    def test_post_add_action_type_fails(self):
        response = self.client.post(reverse('zoning:add_action_type'))
        self.assertEqual(response.status_code, 302)
        self.assertJSONEqual(force_text(response.content), {'result':'Fail', 'msg':'An unknown error occurred'})

1 个答案:

答案 0 :(得分:1)

事实证明问题非常简单,302状态代码是了解我遇到此问题的关键。我的视图中有@login_required装饰器,所以当我在没有登录用户的情况下运行测试时,我被重定向到我的登录视图。由于登录视图返回html而不是JSON,我的响应是无效的JSON,状态代码返回302而不是预期的200.我需要覆盖setUp方法以在数据库中创建用户,然后在测试中调用login本身为了让我的测试正常工作,我的状态代码返回200.感谢@Shang Wang的帮助

完整视图:

@login_required
def add_action_type(request):
    if request.method == 'GET':
        ...
    else:
        form = ActionTypeForm(request.POST)
        if form.is_valid():
            action = form.cleaned_data['action']
            new_type = CaseRequestActionType(action=action)
            new_type.save()

            return JsonResponse({'result':'Success', 'msg':'Success'})
        else:
            return JsonResponse({'result':'Fail', 'msg':'An unknown error occurred'})

更新了测试:

class AddActionTypeTest(TestCase):

    @classmethod
    def setUp(self):
        self.user = User.objects.create_user(username='shawn', email='shawn@...com', password='top_secret')

    def test_post_add_action_type_fails(self):
        self.client.login(username=self.user.username, password='top_secret')
        response = self.client.post(reverse('zoning:add_action_type'))
        self.assertJSONEqual(force_text(response.content), {'result':'Fail', 'msg':'An unknown error occurred'})