0
我正在爲項目編寫一個REST API並且菜單終端正在返回一個帶有項目組的JSON,項目內部的項目可以將任何額外的用戶添加到項目中。使用嵌套資源測試Django REST框架API響應
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)
因爲如果我改變了串行結構,在這種情況下,我想改變測試的歡迎,並寫了這樣大的JSON的是頭痛。 –
而且你將無法保證你的界面合同,因爲如果序列化器發生變化,你的界面將會被忽略。 – Linovia