在单元测试时,如何使用Python / Django比较response.data序列化对象?

时间:2015-11-25 03:27:29

标签: django django-rest-framework

这是我的观点:

class ChatViewSet(viewsets.ModelViewSet):
    serializer_class = ChatSerializer

    def get_queryset(self):
        return Chat.objects.filter(users__in=[self.request.user])

这是我的Serializer:

class ChatSerializer(serializers.ModelSerializer):

    class Meta:
        model = Chat

    def validate_users(self, value):
        for user in value:
            if user in self.context['request'].user.userextended.follow.all() or user == self.context['request'].user:
                pass
            else:
                raise serializers.ValidationError('You cannot chat with a user you are not following.')

        if self.context['request'].user not in value:
            value.append(self.context['request'].user)
        return value

这是我的模特:

class Chat(models.Model):
    users = models.ManyToManyField(User)

这是我的单位测试:

from django.test import TestCase

# Create your tests here.

# Importing this from the DRF example of APIClient unittesting.
from django.core.urlresolvers import reverse

from rest_framework import status

from rest_framework.test import APITestCase

from django.contrib.auth.models import User
from CMSApp.models import Chat
from CMSApp.serializers import ChatSerializer

class ChatTests(APITestCase):
    def setUp(self):
        User.objects.create_user(username='a', password='a', email='a@hotmail.com')

def test_get_chat_list(self):
    """
    Ensure only authenticated users can get their own chat list.
    """
    a = User.objects.get()
    url = reverse('chat-list')
    self.client.login(username='a', password='a')
    Chat.objects.create()
    Chat.objects.get().users.add(a)
    response = self.client.get(url, format='json')
    self.assertEqual(response.status_code, status.HTTP_200_OK)
    # Now, I want to either see if the id of resopnse.data is 1
    # or somehow verify that the chat which was received / created 
    # == the first chat created (chat who's pk / id  is 1). How
    # Would I do this?

我试过了:

    self.assertEqual(response.data.id, 1)

但得到了这个错误:

AttributeError: 'ReturnList' object has no attribute 'id'

当我print(response.data)时,我得到:

[OrderedDict([('id', 1), ('users', [1])])]

我也试过这个:

self.assertEqual(response.data, ChatSerializer(Chat.objects.get()))

但得到了这个错误:

self.assertEqual(response.data, ChatSerializer(Chat.objects.get()))
AssertionError: [OrderedDict([('id', 1), ('users', [1])])] != ChatSerializer(<Chat: Chat object>):
    [134 chars]ll())

知道如何实现我的目标吗?

2 个答案:

答案 0 :(得分:1)

正如您所注意到的,返回的数据类型是Orderdict的列表,因此要访问相同的内容,您必须使用索引。 :)

response_data = simplejson.loads(response.content)
expected_keys = set(['id', 'user'])
# Here first we test if the keys are same in response
# Notice we are checking the 0 index
self.assertEqual(expected_keys, set(response_data[0].keys()))
# To match the value
self.assertEqual(response_data[0]['id'], 1)

答案 1 :(得分:1)

self.assertEqual(response.data.id, 1)

应该是:

self.assertEqual(response.data['id'], 1)

因为它是一本字典。

这就是说,你只需要针对预期的目录声明response.data。 不确定它是否可以与assertEqual一起使用,但使用py.test它是一个简单的断言。

直接从Django REST framework repository获取的示例:

def test_serialize_list(self):
    instances = [
        {'id': 1, 'name': 'tom', 'domain': 'example.com'},
        {'id': 2, 'name': 'ann', 'domain': 'example.com'},
    ]
    serializer = self.Serializer(instances, many=True)
    assert serializer.data == [
        {'id': 1, 'email': 'tom@example.com'},
        {'id': 2, 'email': 'ann@example.com'}
    ]