使用嵌套资源测试Django REST框架API响应

时间:2016-05-12 08:15:25

标签: django django-rest-framework

我正在为项目编写REST API,并且菜单端点返回一个JSON,其中包含项目组内的项目,用户可以添加到项目中的项目。

serializers.py
====================
class ItemExtraSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = ItemExtra
        fields = ('id', 'name', 'price')


class ItemSerializer(serializers.HyperlinkedModelSerializer):
    extras = ItemExtraSerializer(many=True, read_only=True)

    class Meta:
        model = Item
        fields = ('id', 'url', 'name', 'description', 'image', 'code', 'price', 'extras')


class ItemGroupSerializer(serializers.HyperlinkedModelSerializer):
    items = ItemSerializer(many=True, read_only=True)

    class Meta:
        model = ItemGroup
        fields = ('id', 'url', 'name', 'items')


views.py
=========================
class MenuView(ListAPIView):
    serializer_class = ItemGroupSerializer

    def get_queryset(self):
        """
        Return the items inside their groups for search query
        Filtering is one Group name and Item name
        :return:
        """
        queryset = ItemGroup.objects.all()
        search_terms = self.request.query_params.get('q', None)
        if search_terms:
            queryset = Item.objects.search(search_terms)
        return queryset

tests.py
========================

class ItemTestCases(APITestCase):
    def setUp(self):
        self.sandwich_group, created = ItemGroup.objects.get_or_create(name='Sandwiches')
        self.meal_group, created = ItemGroup.objects.get_or_create(name='Meals')
        self.shawarma_sandwich, created = Item.objects.get_or_create(name='Shawarma Sandwich',
                                                                     description='Meat Shawarma Sandwich',
                                                                     price=1.250,
                                                                     code='SW-01',
                                                                     group=self.sandwich_group)
        self.burger_sandwich, created = Item.objects.get_or_create(name='Cheese Burger',
                                                                   description='Single cheese burger Sandwich',
                                                                   price=1.000,
                                                                   code='SW-02',
                                                                   group=self.sandwich_group)
        self.burger_sandwich_extra, created = ItemExtra.objects.get_or_create(name='Extra cheese',
                                                                              price=0.100,
                                                                              item=self.burger_sandwich)
        self.sharawma_meal, created = Item.objects.get_or_create(name='Shawarma Meal',
                                                                 description='Shawarma Sandwich with fries and drink',
                                                                 price=2.000,
                                                                 code='ME-01',
                                                                 group=self.meal_group)
        self.burger_meal, created = Item.objects.get_or_create(name='Burger Meal',
                                                               description='Single cheese burger Sandwich',
                                                               price=2.250,
                                                               code='ME-02',
                                                               group=self.meal_group)
        self.cheese_meal_extra, created = ItemExtra.objects.get_or_create(name='Extra cheese',
                                                                          price=0.100,
                                                                          item=self.burger_meal)
        self.factory = APIRequestFactory()



    def test_menu_GET_request(self):
       item_list = reverse('menu')
       response = self.client.get(item_list)
       self.assertEqual(response.status_code, status.HTTP_200_OK)
       groups = ItemGroup.objects.all()
       expected = ItemGroupSerializer(groups)
       self.assertContains(response, expected.data)

测试的输出是:

AssertionError:HyperlinkedIdentityField需要序列化程序上下文中的请求。在实例化序列化程序时添加context={'request': request}

如何将serlizer呈现为JSON以便将其与API端点JSON进行比较?

更新1: 我弄清楚了,但我认为有一个更清洁的解决方案

我已经创建了辅助函数

def render_many_serializer_as_json(serializer, request, instance):
    serializer_data = serializer(instance=instance, many=True, context={'request': request}).data
    return JSONRenderer().render(serializer_data)

并重写我的测试

def test_menu_GET_request(self):
        item_list = reverse('menu')
        request = self.factory.get(item_list, format='json')
        response = self.client.get(item_list)
        groups = ItemGroup.objects.all()
        expected = render_many_serializer_as_json(ItemGroupSerializer, request, groups)
        self.assertEqual(response.content, expected)

1 个答案:

答案 0 :(得分:0)

为什么复杂的事情? 只需明确写下预期的JSON输出:

- set_fact:
    outer_item: "{{item}}"

- debug:
    msg: "inner item={{item.value}}"
    with_dict: outer_item.value.kafka_topic