AssertionError: 400 != 201 单元测试 Django REST Framework 与 drf-yasg

huangapple go评论59阅读模式
英文:

AssertionError: 400 != 201 Unit Test Django REST Framework with drf-yasg

问题

Here is the translated content:

我正在为我创建的一个名为POST的端点创建一个单元测试:

端点:

class AddJokeAPI(generics.ListAPIView):
    serializer_class = JokeSerializer
    queryset = Joke.objects.all()
    query_param = openapi.Parameter('text', openapi.IN_QUERY,
                             description='Nuevo chiste',
                             type=openapi.TYPE_STRING)

    @swagger_auto_schema(
        operation_description='Guarda en una base de datos el chiste el texto pasado por parámetro',
        manual_parameters=[query_param]
    )
    def post(self, request):
        serializer = self.get_serializer(data={'joke': self.request.GET.get('text')})
        serializer.is_valid(raise_exception=True)
        joke = serializer.save()
        return Response({
            'joke': JokeSerializer(joke, context=self.get_serializer_context()).data,
            'message': 'New joke added',
            'success': True
        }, status=status.HTTP_201_CREATED)

如果您看到,POST方法中我必须发送一个名为"text"的POST查询参数,以在模型"Joke"中注册它并接收HTTP状态码201。

这是用于调用该端点的test.py方法:

class JokesTestCase(TestCase):

    def setUp(self):
        self.client = APIClient()

    def test_post_joke(self):
        payload = {
            'text': 'Test Joke'
        }
        response = self.client.post('/api/jokes/add', payload)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

我收到的错误是:

self.assertEqual(response.status_code, status.HTTP_201_CREATED) AssertionError: 400 != 201

正如您所看到的,错误是我正在发出一个错误的请求,但我不知道为什么会得到该错误。

如果我尝试使用这个路径进行请求,测试将如我所预期的那样通过:

response = self.client.post('/api/jokes/add?text=Test%20Joke')

更新:这是我的serializers.py

class JokeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Joke
        fields = ('id', 'joke')

    def create(self, validated_data):
        joke = Joke.objects.create(**validated_data)
        return joke

有人可以帮助我吗?谢谢你。

英文:

i am creating an unittest for a endpoint POST that i created:

Endpoint:

class AddJokeAPI(generics.ListAPIView):
    serializer_class = JokeSerializer
    queryset = Joke.objects.all()
    query_param = openapi.Parameter('text', openapi.IN_QUERY,
                             description="Nuevo chiste",
                             type=openapi.TYPE_STRING)

    @swagger_auto_schema(
        operation_description="Guarda en una base de datos el chiste el texto pasado por parámetro",
        manual_parameters=[query_param]
    )
    def post(self, request):
        serializer = self.get_serializer(data={"joke": self.request.GET.get('text')})
        serializer.is_valid(raise_exception=True)
        joke = serializer.save()
        return Response({
            "joke": JokeSerializer(joke, context=self.get_serializer_context()).data,
            "message": "New joke added",
            "success": True
        }, status=status.HTTP_201_CREATED)

If you can see, in the POST method i have to send a POST query param called "text" to register it in the model "Joke" and receive a 201 HTTP Status.

This is my test.py method to call that endpoint:

class JokesTestCase(TestCase):

    def setUp(self):
        self.client = APIClient()

    def test_post_joke(self):
        payload = {
            'text': 'Test Joke'
        }
        response = self.client.post('/api/jokes/add', payload)
        self.assertEqual(response.status_code, status.HTTP_201_CREATED)

the error that i am getting is:

self.assertEqual(response.status_code, status.HTTP_201_CREATED) AssertionError: 400 != 201

as you can see the error is that i am making a bad request, but i dont know exactly why i am getting that error.

If i try to make a request with this path, the test will pass as i expect:

response = self.client.post('/api/jokes/add?text=Test%20Joke')

UPDATE: This is my serializers.py

class JokeSerializer(serializers.ModelSerializer):
    class Meta:
        model = Joke
        fields = ('id', 'joke')

    def create(self, validated_data):
        joke = Joke.objects.create(**validated_data)
        return joke

Anyone can help me with this? Thank you

答案1

得分: 1

错误是因为您在请求体中发送了"payload",而不是查询参数。

您试图从request.GET获取文本,但不存在,会返回None。

当您实例化序列化器时,传递的数据将为键"joke"的值为None,这将使其无效并引发异常,即validationError,即400 BAD Request。

因此,您的函数将从这一行返回。

因此,您的断言将失败。400!=201

要解决此问题,请将笑话作为查询参数发送,而不是请求体。

英文:

The error is caused because you are sending "payload" in your request body instead of query params.

response = self.client.post('/api/jokes/add', payload)

You are trying to get text from request.GET which is non existent and will return None.

serializer = self.get_serializer(data={"joke": self.request.GET.get('text')})

And when you instantiate your serializer when passing data which will have value None for key joke, it will not be valid and will raise exception which will be a validationError i.e. 400 BAD Request.

serializer.is_valid(raise_exception=True)

Your function will be returned from this line.

Hence, your assertion will fail. 400 != 201

To solve this, send joke as a query param instead of a request body.

response = self.client.post('/api/jokes/', params={'text': 'Test Joke'})

huangapple
  • 本文由 发表于 2023年4月13日 22:33:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76006681.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定