Django覆盖Unittest中的settings.py对象不起作用

时间:2019-04-08 07:39:44

标签: python django django-rest-framework django-unittest

有使用Django Rest Framework的Django应用。设置文件包含一个具有以下设置的对象:

settings.py

REST_FRAMEWORK = {
    ...
    'DEFAULT_THROTTLE_RATES': {
        'burst': '30/second',
    },
    ...
}

单元测试应该可以测试节流的实际效果。但是,Django Test模块提供的工具(SimpleTestCase.settingsoverride_settingsmodify_settings)均无法正常工作:

SimpleTestCase.settings

class ThrottlingTest(RestApiTestCase):
    def test_per_second_throttling(self):
        new_config = settings.REST_FRAMEWORK
        new_config['DEFAULT_THROTTLE_RATES']['burst'] = '1/second'
        with self.settings(REST_FRAMEWORK=new_config):
        for _ in range(0, 2):
            response = self.client.get(self.api_reverse('foo'))
        self.assertEqual(response.status_code, 429)  # fails, 200 != 429

override_settings

class ThrottlingTest(RestApiTestCase):
    new_config = settings.REST_FRAMEWORK
    new_config['DEFAULT_THROTTLE_RATES']['burst'] = '1/second'

    @override_settings(REST_FRAMEWORK=new_config)
    def test_per_second_throttling(self):
        for _ in range(0, 2):
            response = self.client.get(self.api_reverse('foo'))
        self.assertEqual(response.status_code, 429)  # fails, 200 != 429

这两种方法都适用于原始变量和列表,但是对于对象而言失败。

文档状态:

  

给定一个类时,这些装饰器直接修改该类并返回它;他们不会创建并返回修改后的副本。

因此实际上应该起作用。

任何线索如何处理?

1 个答案:

答案 0 :(得分:1)

我认为这实际上是Django REST Framework中的错误/缺失功能。设置测试工具(SimpleTestCase.settingsoverride_settingsmodify_settings)发出setting_changed信号,并依赖每个组件进行相应的更新。

Django REST Framework 确实侦听此信号(source),但这对节流率没有影响,因为节流率是类属性(source )。

话虽如此,我同意@Aarif的观点,因为DRF本身具有涵盖此功能的测试,因此无需测试。

此外,请注意,您正在修改现有的REST_FRAMEWORK设置字典。而是创建一个副本:

new_config = settings.REST_FRAMEWORK.copy()