代码之家  ›  专栏  ›  技术社区  ›  lmiguelvargasf

如何使用DRF和HyperlinkedModelSerializer序列化程序测试POST方法

  •  1
  • lmiguelvargasf  · 技术社区  · 6 年前

    我正在使用Django Rest框架(DRF),并尝试测试POST方法。

    这些是我的模型:

    class CustomUser(AbstractUser):
        def __str__(self):
            return self.email
    
        class Meta:
            ordering = ('id',)
            verbose_name = 'user'
    
    
    class Brand(Group):
        owner = models.ForeignKey(User,
                                  on_delete=models.CASCADE,
                                  related_name='%(class)ss',
                                  related_query_name='%(class)s')
        description = models.TextField('description', max_length=3000, blank=True)
        facebook_url = models.URLField('facebook url', blank=True)
        twitter_url = models.URLField('twitter url', blank=True)
        instagram_url = models.URLField('instagram url', blank=True)
        pinterest_url = models.URLField('pinterest url', blank=True)
        portfolio_url = models.URLField('portfolio url',  blank=True)
        phone_number = PhoneNumberField('phone number', blank=True)
    

    class CustomUserSerializer(HyperlinkedModelSerializer):
        brands = HyperlinkedRelatedField(
            many=True,
            read_only=True,
            view_name='brand-detail'
        )
    
        class Meta:
            model = CustomUser
            fields = (
                'url',
                'username',
                'email',
                'brands',
            )
    
    class BrandSerializer(HyperlinkedModelSerializer):
        addresses = HyperlinkedRelatedField(many=True,
                                            read_only=True,
                                            view_name='address-detail')
    
        class Meta:
            model = Brand
            fields = (
                'url',
                'name',
                'owner',
                'description',
                'facebook_url',
                'twitter_url',
                'instagram_url',
                'pinterest_url',
                'portfolio_url',
                'phone_number',
            )
    

    class CustomUserViewSet(ModelViewSet):
        """"A view set for viewing and editing custom users."""
        queryset = CustomUser.objects.all()
        serializer_class = CustomUserSerializer
    
    
    class BrandViewSet(ModelViewSet):
        """A view set for viewing and editing brands."""
        queryset = Brand.objects.all()
        serializer_class = BrandSerializer
    

    这是我的测试,我正在使用pytest:

    @pytest.mark.django_db
    def test_create_brand_with_valid_data(client):
        """Tests POST method with valid data to create a Brand instance."""
        user = CustomUser.objects.create(username='x',
                                         email='x@example.com',
                                         password='abc123', )
    
        data = {
            'owner': f'http://testserver/api/users/{user.id}/',
            'name': 'NA',
        }
    
        print(data)
    
        response = client.post(reverse('address-list'),
                               data=json.dumps(data),
                               content_type='application/json')
    
        assert response.status_code == HTTP_201_CREATED
    

    我的回答不是201,而是400,所以我做错了什么,但我不知道是什么。

    _________________________________________________________________________________ test_create_brand_with_valid_data _________________________________________________________________________________
    
    client = <django.test.client.Client object at 0x10c2199b0>
    
        @pytest.mark.django_db
        def test_create_brand_with_valid_data(client):
            """Tests POST method with valid data to create a Brand instance."""
            user = CustomUser.objects.create(username='x',
                                             email='x@example.com',
                                             password='abc123', )
    
            data = {
                'owner': f'http://testserver/api/users/{user.id}/',
                'name': 'NA',
            }
    
            print(data)
    
            response = client.post(reverse('address-list'),
                                   data=json.dumps(data),
                                   content_type='application/json')
    
    >       assert response.status_code == HTTP_201_CREATED
    E       assert 400 == 201
    E        +  where 400 = <Response status_code=400, "application/json">.status_code
    
    api/tests/test_brand.py:98: AssertionError
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   lmiguelvargasf    6 年前

    这是相当尴尬的,所以问题是我请求到了错误的端点。以下代码解决了我的问题,也避免了对url进行硬编码:

    import json
    from rest_framework.request import Request
    from rest_framework.reverse import reverse
    from rest_framework.status import (HTTP_200_OK,
                                       HTTP_404_NOT_FOUND,
                                       HTTP_201_CREATED,
                                       HTTP_400_BAD_REQUEST,
                                       HTTP_204_NO_CONTENT)
    from rest_framework.test import APIRequestFactory
    
    @pytest.mark.django_db
    def test_create_brand_with_valid_data(client):
        """Tests POST method with valid data to create a Brand instance."""
        user = CustomUser.objects.create(username='x',
                                         email='x@example.com',
                                         password='abc123', )
        factory = APIRequestFactory()
        request = factory.get('/')
    
        context = {'request': Request(request)}
        user_serializer = CustomUserSerializer(user, context=context)
    
        data = {
            'owner': user_serializer.data['url'],
            'name': 'NA',
        }
    
        response = client.post(reverse('brand-list'),
                               data=json.dumps(data),
                               content_type='application/json')
    
        assert response.status_code == HTTP_201_CREATED
    

    这项测试非常有效。