Rob*_*ter 6 django unit-testing django-settings django-rest-framework http-token-authentication
我基本上想打开 TokenAuthentication 但仅用于 2 个单元测试。到目前为止,我看到的唯一选项是@override_settings(...)用于替换 REST_FRAMEWORK 设置值。
REST_FRAMEWORK_OVERRIDE={
'PAGINATE_BY': 20,
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework_csv.renderers.CSVRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
@override_settings(REST_FRAMEWORK=REST_FRAMEWORK_OVERRIDE)
def test_something(self):
Run Code Online (Sandbox Code Playgroud)
这不起作用。我可以在装饰器之前和之后打印设置,并看到这些值发生了变化,但 django 似乎并不尊重它们。它允许使用测试客户端或 DRF APIClient 对象发送的所有请求无需身份验证即可通过。当我预计 401 未经授权时,我会收到 200 回复。
如果我将相同的字典插入到 config 文件夹中的 test_settings.py 文件中,一切都会按预期工作。然而,就像我说的,我只想为几个单元测试打开身份验证,而不是全部。我的想法是 Django 在初始化后永远不会重新访问 DRF 的设置。因此,即使设置值正确,也不会使用它们。
有没有人遇到过这个问题并找到了解决方案?还是解决办法?
以下解决方法对我很有效:
from rest_framework.views import APIView
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.authentication import TokenAuthentication
try:
from unittest.mock import patch
except ImportError:
from mock import patch
@patch.object(APIView, 'authentication_classes', new = [TokenAuthentication])
@patch.object(APIView, 'permission_classes', new = [IsAuthenticatedOrReadOnly])
class AuthClientTest(LiveServerTestCase):
# your tests goes here
Run Code Online (Sandbox Code Playgroud)
只是想我会提到我是如何解决这个问题的。它不漂亮,如果有人有任何清理它的建议,我们非常欢迎!正如我之前提到的,我遇到的问题已记录在此处(https://github.com/tomchristie/django-rest-framework/issues/2466),但修复方案并不那么明确。除了重新加载 DRF 视图模块之外,我还必须重新加载应用程序视图模块才能使其正常工作。
import os
import json
from django.conf import settings
from django.test.utils import override_settings
from django.utils.six.moves import reload_module
from rest_framework import views as drf_views
from rest_framework.test import force_authenticate, APIRequestFactory, APIClient
from apps.contact import views as cm_views
from django.core.urlresolvers import reverse
from django.test import TestCase
from unittest import mock
REST_FRAMEWORK_OVERRIDE={
'PAGINATE_BY': 20,
'TEST_REQUEST_DEFAULT_FORMAT': 'json',
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework_csv.renderers.CSVRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.IsAuthenticated',
),
}
def test_authenticated(self):
with override_settings(REST_FRAMEWORK=REST_FRAMEWORK_OVERRIDE):
# The two lines below will make sure the views have the correct authentication_classes and permission_classes
reload_module(drf_views)
reload_module(cm_views)
from apps.contact.views import AccountView
UserModelGet = mock.Mock(return_value=self.account)
factory = APIRequestFactory()
user = UserModelGet(user='username')
view = AccountView.as_view()
# Test non existent account
path = self.get_account_path("1thiswillneverexist")
request = factory.get(path)
force_authenticate(request, user=user)
response = view(request, account_name=os.path.basename(request.path))
self.assertEquals(response.status_code, 200, "Wrong status code")
self.assertEqual(json.loads(str(response.content, encoding='utf-8')), [], "Content not correct for authenticated account request")
# Reset the views permission_classes and authentication_classes to what they were before this test
reload_module(cm_views)
reload_module(drf_views)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2436 次 |
| 最近记录: |