Django 重写 settings.py 单元测试中的对象不起作用

Django overriding settings.py OBJECT in unittest not working

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

settings.py

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

单元测试应该测试节流是否有效。然而,Django 测试模块 (SimpleTestCase.settings, override_settings, modify_settings) 提供的工具 none 确实有效:

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

这两种方法都适用于原始变量和列表,但不适用于对象。

文档状态:

When given a class, these decorators modify the class directly and return it; they don’t create and return a modified copy of it.

所以它实际上应该有效。

任何线索如何处理这个?

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

Django REST Framework 监听此信号 (source), but this has no effect in on the throttle rate because the throttle rate is a class attribute (source)。

话虽这么说,我同意@Aarif 的观点,这不需要测试,因为 DRF 本身有涵盖此功能的测试。

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

new_config = settings.REST_FRAMEWORK.copy()