There is Django app that uses Django Rest Framework. The settings file contains an object with the settings:
settings.py
REST_FRAMEWORK = {
...
'DEFAULT_THROTTLE_RATES': {
'burst': '30/second',
},
...
}
The unittest is supposed to test the throttling actually works. However none of the tools provided by Django Test module (SimpleTestCase.settings, override_settings, modify_settings) actually work:
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
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
Both methods work fine for primitive variables and lists, however fail for the object.
The docs state:
When given a class, these decorators modify the class directly and return it; they don’t create and return a modified copy of it.
So it actually supposed to work.
Any clues how to handle this?
I think this actually a bug/missing feature in Django REST Framework. The settings test tools (SimpleTestCase.settings
, override_settings
, modify_settings
) send out a setting_changed
signal and rely on every component to update accordingly.
Django REST Framework does listen to this signal (source), but this has no effect in on the throttle rate because the throttle rate is a class attribute (source).
That being said, I agree with @Aarif that this does not need to be tested because DRF itself has tests covering this feature.
Also, note that you are modifying the existing REST_FRAMEWORK
settings dictionary. Create a copy instead:
new_config = settings.REST_FRAMEWORK.copy()