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.settings
、override_settings
、modify_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()
有使用 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.settings
、override_settings
、modify_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()