django REST框架-如何正确地对自定义解析器进行单元测试

sirbozc5  于 2022-11-26  发布在  Go
关注(0)|答案(3)|浏览(135)

我已经在谷歌上搜索了一段时间了,但我仍然找不到一个匹配的!我写了一个相当复杂的自定义解析器来转换传入的数据,以匹配我的序列化器结构。
我希望对此进行适当的单元测试,以确保在更改或重构代码时,它仍能正常工作。
但我不知道怎么做!在互联网上没有这样的例子,只是这样天真地使用它:

def test_me(self):
    parser_class = MyFancyParser()
    parser_class.parse(stream={'id': 27, 'other_data': 117})

...不起作用,因为它需要stream而不是数据字典。
对这个主题有什么想法吗?

p8ekf7hl

p8ekf7hl1#

来自DRF文档
类似数据流的对象,表示要求的主体。
因此,dict {'id': 27, 'other_data': 117}必须转换为bytesstring

最小可验证示例

import io
import json
from django.test import TestCase

from rest_framework.parsers import JSONParser

class MyFancyParser(JSONParser):
    pass

class TestJSONParser(TestCase):

    def test_me(self):
        parser_class = MyFancyParser()
        json_str = json.dumps({"id": 27, "other_data": 117})
        stream = io.BytesIO(json_str.encode())
        parsed_data = parser_class.parse(stream=stream)
        self.assertEqual(parsed_data, {'id': 27, 'other_data': 117})
hmae6n7t

hmae6n7t2#

Stream是任何可以读取的东西(有一个read方法)。所以你需要用io模块 Package 任何字符串。
记住只测试你的代码。既然drf解析器已经测试过了,也许可以看看drf是如何测试解析器的?
范例

class TestFormParser(TestCase):
    def setUp(self):
        self.string = "field1=abc&field2=defghijk"

    def test_parse(self):
        """ Make sure the `QueryDict` works OK """
        parser = FormParser()

        stream = io.StringIO(self.string)
        data = parser.parse(stream)

        assert Form(data).is_valid() is True
9bfwbjaz

9bfwbjaz3#

好的,我所做的是将逻辑封装在一个自定义服务/类中,然后在解析器中调用该类。

class MyParser(parsers.JSONParser):
    def parse(self, stream, *args, **kwargs):
        raw_data = super().parse(stream, *args, **kwargs)
        pk = args[1]['kwargs']['pk']
        service = MyService()
        return service.parse_incoming_data(raw_data, pk)

好处显而易见:我可以测试和构建我的代码,因为我喜欢没有任何考虑DRF的细节。
如果解析器仍然工作(例如在更新DRF之后),则通过使用API客户端测试视图集来隐式处理“一般”测试。

相关问题