单元测试视图时Django assertJSONEqual出错

Error with Django assertJSONEqual when unit testing view

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

编辑:
追溯

1
======================================================================

错误:tearDownClass(zoning_intake.tests.AddActionTypeTest)

Traceback(最近一次调用最后一次):
文件"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)

Traceback(最近一次调用最后一次):
在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'保留测试数据库...
为别名"其他"保留测试数据库...

我的看法:

1
2
3
4
5
6
7
8
9
    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'})

我的测试:

1
2
3
4
5
6
7
8
9
10
11
12
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'})


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

完整视图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@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'})

更新测试:

1
2
3
4
5
6
7
8
9
10
class AddActionTypeTest(TestCase):

    @classmethod
    def setUp(self):
        self.user = User.objects.create_user(username='shawn', email='[email protected]', 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'})