1

我基本上想打開TokenAuthentication,但僅用於2個單元測試。我目前看到的唯一選擇是使用@override_settings(...)替換REST_FRAMEWORK設置值。運行時單元測試Django Rest框架身份驗證

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): 

這是行不通的。我可以在修飾器之前和之後打印設置,並看到值已更改,但django似乎並未尊重它們。它允許所有使用測試客戶端或DRF APIClient對象發送的請求無需驗證。當我預計401未經授權時,我收到200條迴應。

如果我在config文件夾的test_settings.py文件中插入相同的字典,一切都按預期工作。然而就像我說過的,我只想打開幾個單元測試的認證,而不是全部。我的想法是,Django在初始化之後永遠不會重新訪問DRF的設置。所以即使設置值是正確的,它們也不會被使用。

有沒有人遇到這個問題,並找到了解決辦法?或解決方法?

+0

使用提供'從rest_framework.settings導入api_settings'審查源代碼會給你一個提示如何覆蓋: https://開頭github.com/tomchristie/django-rest-framework/blob/master/rest_framework/settings.py – petkostas 2015-03-31 11:47:04

+0

我剛剛發現這個問題,https://github.com/tomchristie/django-rest-framework/issues/2466看起來像我的問題可能還沒有解決:/ – 2015-03-31 18:32:21

回答

1

只是想我會提到我是如何解決這個問題的。這不是很好,如果有人有任何建議來清理它們,它們是非常值得歡迎的!正如我前面提到的,我遇到的問題記錄在這裏(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) 
+0

我還應該提到,導入不喜歡重新加載模塊... – 2015-04-01 20:40:17

0

以下解決方法很適合我:

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