django lazy翻译有时会出现在单元测试中的response.data中

时间:2015-08-19 00:10:43

标签: django python-2.7 unit-testing unicode django-rest-framework

我正在为用django-rest-framework编写的django api编写单元测试,并且我遇到来自生成400_BAD_REQUEST的调用看似不一致的响应数据。

当我发出请求失败因为它引用了无效的主键时,repr(response.data)是一个字符串,我可以检查子字符串"Invalid pk"。但是当我发出请求因为尝试创建非唯一对象而失败时,repr(response.data)包含{'name': [<django.utils.functional.__proxy__ object at 0x7f3ccdcb26d0>]}而不是预期的{'name': ['This field must be unique.']}。当我对真实服务器进行实际POST调用时,我会使用{'name': ['This field must be unique.']}得到预期的400响应。

以下是代码示例:

class GroupViewTests(APITestCase):
    def test_post_existing_group(self):
        """
        Use POST to update a group at /groups
        """
        # create a group
        # self.group_data returns a valid group dict
        data = self.group_data(1)
        url = reverse('group-list')
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        # create the same group again
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        # this fails
        self.assertIn('must be unique', repr(response.data))
    def test_create_group_with_nonexistent_user(self):
        """
        Create a group with an invalid userid in it.
        """
        url = reverse('group-list')
        data = self.group_data(5)
        data.update({'users': ['testnonexistentuserid']})
        response = self.client.post(url, data, format='json')
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
        # this succeeds
        self.assertIn('Invalid pk', repr(response.data))

我只使用默认的中间件。

根据我在网上找到的内容,__proxy__对象是延迟翻译的表示,可以通过调用unicode(obj)obj.__unicode__将其呈现为字符串。实际上,response.data['name'][0].__unicode__确实返回了预期值,但调用unicode(response.data)而不是repr(response.data)仍然返回由内存地址标识的对象。

任何人都可以解释这里发生了什么,以及如何解决它?我现在可以解决这个问题,但我想知道解决这个问题的“真正方法”。这可能是django或django-rest-framework中的错误吗?

1 个答案:

答案 0 :(得分:0)

使用version代替response.content

response.data包含json输出,就像您的客户端会收到它一样。如果您的自定义渲染器更改了响应,因为response.content未呈现,但是response.data是,那么它也很有用。

例如:

response.content