如何重写测试设置中的一个值
How can I rewrite one value in the settings for the test
如何在测试设置中重写 'user': '5/分钟' on 'user': '2/day'
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'user': '5/minute'
}
}
如何使用@override_settings 或 mb 进行上下文管理?
我只需要在一次测试中应用它,我不能重写整个字典
def test_mytest(self):
value = settings.REST_FRAMEWORK
value['DEFAULT_THROTTLE_RATES'] = {'user':'2/day'}
data1 = {}
data2 = {}
data3 = {}
with self.settings(REST_FRAMEWORK=value):
resp1 = self.client.post(self.url, data1, format='json')
resp2 = self.client.post(self.url, data1, format='json')
resp3 = self.client.post(self.url, data1, format='json')
assert resp3.status_code == 429, resp3.data
但是没有429错误,虽然值已经改变了
解决方案 1:使用 @override_default()
包装器
您想将包装函数应用到您希望用此值覆盖的 viewset
:
from rest_framework.throttling import UserRateThrottle
class UserViewSet(viewsets.ViewSet):
@api_view(['PUT'])
@throttle_classes([UserRateThrottle])
@override_settings(REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']['user'] = "2/day")
def update(self, request, pk=None):
...
在您希望应用此覆盖自定义值的任何视图或视图集之前添加包装。
您也想在 settings.py
:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '13500/day'
}
}
解决方案 2:自定义节流 class
但是,如果您希望在测试环境中使用不同的节流率,也许可以在 settings.py
中尝试以下操作:
TEST = True ## <-- Set to False when not in testing!!
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.CustomUserRateThrottle'
)
}
并指定您自己的自定义节流 class:
from django.conf import settings
class CustomUserRateThrottle(throttling.UserRateThrottle):
if settings.TEST:
THROTTLE_RATES = 'DEFAULT_THROTTLE_RATES': {
'user': '13500/day',
}
else:
THROTTLE_RATES = 'DEFAULT_THROTTLE_RATES': {
'user': '2/day',
}
return settings.TEST # <-- Custom throttling classes must always return either True or False, so this makes sense.
解决方案 3:直接在您的 "testing shell":
包括我们上面定义的自定义包装器,但这次是在 test.py
中的 test_something()
方法中:
from django.conf import settings
from django.test import TestCase
class TestCase(TestCase):
def test_something(self):
with self.settings(REST_FRAMEWORK = ['DEFAULT_THROTTLE_RATES']['user'] = '13500/day'):
# START TESTING HERE WITH TEST SETTINGS
根据您的用例,您可以采用以下方式之一:
建议 1: 如果你想 覆盖一些特定测试用例中的设置 你可以使用 @override_settings
装饰器。但是,如果您希望对所有测试用例都这样做,那么这没有任何意义,如果是这种情况,那么您可以遵循建议 2.
建议 2 : 这是更通用和有效的解决方案。
您可以为各种 运行ning 环境(在设置 python 模块内)设置多个设置文件,如下所示:
base.py
(包含您所有的基本设置)
local.py
(从此处导入 * 和 override/add 特定于 local/dev 环境的设置)
test.py
(从此处导入 * 和 override/add 特定于测试环境的设置)
- 您还可以在
prod.py
或其他内容中针对生产环境进行特定设置。
使用此设置可以 运行 测试 python manage.py test --settings=yourproject.settings.test
from unittest import mock
@mock.patch('rest_framework.throttling.SimpleRateThrottle.get_rate')
def test_api(self, get_rate):
get_rate.return_value = '1/minute'
from rest_framework.settings import api_settings
print(api_settings.DEFAULT_THROTTLE_RATES)
print(api_settings.user_settings)
url = 'api'
response = self.client.get(url)
self.assertEqual(response.status_code, HTTP_200_OK)
response = self.client.get(url)
self.assertEqual(response.status_code, HTTP_429_TOO_MANY_REQUESTS)
如何在测试设置中重写 'user': '5/分钟' on 'user': '2/day'
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_RATES': {
'user': '5/minute'
}
}
如何使用@override_settings 或 mb 进行上下文管理? 我只需要在一次测试中应用它,我不能重写整个字典
def test_mytest(self):
value = settings.REST_FRAMEWORK
value['DEFAULT_THROTTLE_RATES'] = {'user':'2/day'}
data1 = {}
data2 = {}
data3 = {}
with self.settings(REST_FRAMEWORK=value):
resp1 = self.client.post(self.url, data1, format='json')
resp2 = self.client.post(self.url, data1, format='json')
resp3 = self.client.post(self.url, data1, format='json')
assert resp3.status_code == 429, resp3.data
但是没有429错误,虽然值已经改变了
解决方案 1:使用 @override_default()
包装器
您想将包装函数应用到您希望用此值覆盖的 viewset
:
from rest_framework.throttling import UserRateThrottle
class UserViewSet(viewsets.ViewSet):
@api_view(['PUT'])
@throttle_classes([UserRateThrottle])
@override_settings(REST_FRAMEWORK['DEFAULT_THROTTLE_RATES']['user'] = "2/day")
def update(self, request, pk=None):
...
在您希望应用此覆盖自定义值的任何视图或视图集之前添加包装。
您也想在 settings.py
:
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
),
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '13500/day'
}
}
解决方案 2:自定义节流 class
但是,如果您希望在测试环境中使用不同的节流率,也许可以在 settings.py
中尝试以下操作:
TEST = True ## <-- Set to False when not in testing!!
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': (
'rest_framework.throttling.CustomUserRateThrottle'
)
}
并指定您自己的自定义节流 class:
from django.conf import settings
class CustomUserRateThrottle(throttling.UserRateThrottle):
if settings.TEST:
THROTTLE_RATES = 'DEFAULT_THROTTLE_RATES': {
'user': '13500/day',
}
else:
THROTTLE_RATES = 'DEFAULT_THROTTLE_RATES': {
'user': '2/day',
}
return settings.TEST # <-- Custom throttling classes must always return either True or False, so this makes sense.
解决方案 3:直接在您的 "testing shell":
包括我们上面定义的自定义包装器,但这次是在 test.py
中的 test_something()
方法中:
from django.conf import settings
from django.test import TestCase
class TestCase(TestCase):
def test_something(self):
with self.settings(REST_FRAMEWORK = ['DEFAULT_THROTTLE_RATES']['user'] = '13500/day'):
# START TESTING HERE WITH TEST SETTINGS
根据您的用例,您可以采用以下方式之一:
建议 1: 如果你想 覆盖一些特定测试用例中的设置 你可以使用 @override_settings
装饰器。但是,如果您希望对所有测试用例都这样做,那么这没有任何意义,如果是这种情况,那么您可以遵循建议 2.
建议 2 : 这是更通用和有效的解决方案。
您可以为各种 运行ning 环境(在设置 python 模块内)设置多个设置文件,如下所示:
base.py
(包含您所有的基本设置)local.py
(从此处导入 * 和 override/add 特定于 local/dev 环境的设置)test.py
(从此处导入 * 和 override/add 特定于测试环境的设置)- 您还可以在
prod.py
或其他内容中针对生产环境进行特定设置。
使用此设置可以 运行 测试 python manage.py test --settings=yourproject.settings.test
from unittest import mock
@mock.patch('rest_framework.throttling.SimpleRateThrottle.get_rate')
def test_api(self, get_rate):
get_rate.return_value = '1/minute'
from rest_framework.settings import api_settings
print(api_settings.DEFAULT_THROTTLE_RATES)
print(api_settings.user_settings)
url = 'api'
response = self.client.get(url)
self.assertEqual(response.status_code, HTTP_200_OK)
response = self.client.get(url)
self.assertEqual(response.status_code, HTTP_429_TOO_MANY_REQUESTS)