首页 > 解决方案 > OrderingFilter DRF 的单元测试

问题描述

我有一个模型:

class Trade(models.Model):
    name = models.CharField(max_length=255, unique=True)
    is_active = models.BooleanField('Active', default=True)
    is_deleted = models.BooleanField('Deleted', default=False)

views.py

class TradeViewSet(viewsets.ModelViewSet):
    queryset = Trade.objects.all()
    permission_classes = [permissions.IsAuthenticated]
    serializer_class = TradeSerializer
    filter_backends = [
        DjangoFilterBackend,
        CaseInsensitiveOrderingFilter,
        SearchFilter
    ]

过滤CaseInsensitiveOrderingFilter

class CaseInsensitiveOrderingFilter(OrderingFilter):
    """
    Custom filter to order case insensitive fields as CharField and TextField.
    To define filter it's needed to add char or text fields to list:
    ordering_case_insensitive_fields = ["field"]
    """
    def filter_queryset(self, request, queryset, view):
        ordering = self.get_ordering(request, queryset, view)
        insensitive_ordering = getattr(view, 'ordering_case_insensitive_fields', ())

        if ordering:
            new_ordering = []
            for field in ordering:
                if field.lstrip('-') in insensitive_ordering:
                    if field.startswith('-'):
                        new_ordering.append(Lower(field[1:]).desc())
                    else:
                        new_ordering.append(Lower(field).asc())
                else:
                    new_ordering.append(field)
            return queryset.order_by(*new_ordering)

        return queryset

和简单的序列化器

class TradeSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Trade
        fields = (
            'id', 'name', 'is_active', 'is_deleted',
        )
        read_only_fields = ('is_deleted', 'id')

我的测试.py

class TradeAPITest(BaseAPITestCaseSetup):
    data = {
        'name': 'Trade Name 012000',
        'is_active': True,
    }

    def setUp(self):
        super().setUp()
        self.trade = Trade.objects.create(**self.data)
        factories.TradeFactory.create_batch(10)
        self.test_data = {
            'name': 'Trade Name 2',
            'is_active': True,
        }
    
    def test_ordering_by_name_ascending(self):
        url = reverse('trades-list') + '?ordering=name'
        response = self.client.get(url)
        response_results = response.json().get('results')
        expected_result = sorted(response_results, key=lambda i: i['name'].lower())
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response_results, expected_result)

    def test_ordering_by_name_descending(self):
        url = reverse('trades-list') + '?ordering=-name'
        response = self.client.get(url)
        response_results = response.json().get('results')
        expected_result = sorted(
            response_results, key=lambda i: i['name'].lower(), reverse=True
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response_results, expected_result)

我想测试订购是否正确,对于模型生成,我使用工厂和 Faker 一切都在本地正常工作。但是在某些情况下,当我推送到存储库时,我的测试没有通过管道。

self = <tests.trades.test_trades_base_views.TradeAPITest testMethod=test_ordering_by_name_descending>
    def test_ordering_by_name_descending(self):
        url = reverse('trades-list') + '?ordering=-name'
        response = self.client.get(url)
        response_results = response.json().get('results')
        expected_result = sorted(
            response_results, key=lambda i: i['name'].lower(), reverse=True
        )
        self.assertEqual(response.status_code, status.HTTP_200_OK)
>       self.assertEqual(response_results, expected_result)
E       AssertionError: Lists differ: [{'id[451 chars]d': 57, 'name': 'I process environmental story[386 chars]lse}] != [{'id[451 chars]d': 52, 'name': 'Interview because data such d[386 chars]lse}]
E       
E       First differing element 5:
E       {'id': 57, 'name': 'I process environmental story[38 chars]alse}
E       {'id': 52, 'name': 'Interview because data such d[43 chars]alse}

我不知道是什么问题

标签: djangounit-testingdjango-rest-frameworkdjango-unittest

解决方案


推荐阅读