【问题标题】:django REST Framework - How to properly unittest a custom parserdjango REST Framework - 如何正确地对自定义解析器进行单元测试
【发布时间】:2021-04-25 21:24:11
【问题描述】:

我已经在谷歌上搜索了一段时间,但仍然无法找到一个匹配项!我编写了一个非常精细的自定义解析器来转换传入的数据以匹配我的序列化器结构。

我想对它进行适当的单元测试,以确保它在更改或重构我的代码时仍然有效。

但我不知道怎么做!互联网上几乎没有例子,只是像这样天真地使用它:

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

... 不起作用,因为它需要 stream 而不是数据字典。

关于这个话题有什么想法吗?

提前致谢!

【问题讨论】:

  • 好的,我可以将逻辑封装在服务方法中并进行测试……但这真的是这样吗?

标签: django unit-testing django-rest-framework


【解决方案1】:

来自DRF doc

表示请求正文的类流对象。

因此,字典 {'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})

【讨论】:

    【解决方案2】:

    Stream 是可以读取的任何内容(具有read 方法)。所以你需要用io模块包装任何字符串。

    请记住只测试您的代码。由于 drf 解析器已经过测试,不妨看看 how drf tests test parsers?

    例子

    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
    

    【讨论】:

      【解决方案3】:

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

      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 客户端测试视图集来隐式处理的。

      【讨论】:

        猜你喜欢
        • 2011-02-02
        • 2016-09-07
        • 2022-12-21
        • 2020-01-06
        • 2015-01-27
        • 1970-01-01
        • 2014-03-22
        • 2014-12-07
        • 2018-05-27
        相关资源
        最近更新 更多