6

私は基本的に 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):

これは機能していません。デコレータの前後の設定を印刷して、値が変更されたことを確認できますが、django はそれらを尊重していないようです。テスト クライアントまたは DRF APIClient オブジェクトを使用して送信されたすべてのリクエストを認証なしで許可します。401 無許可と予想されるのに 200 の応答が返ってきます。

同じ辞書を構成フォルダーの test_settings.py ファイルに挿入すると、すべてが期待どおりに機能します。ただし、私が言ったように、すべてではなく、いくつかの単体テストの認証のみを有効にしたいのです。私の考えでは、Django は初期化後に DRF の設定を再確認することはありません。そのため、設定値が正しい場合でも、それらは使用されません。

誰かがこの問題に遭遇し、解決策を見つけましたか? または回避策?

4

3 に答える 3

6

次の回避策は私にとってはうまくいきます:

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
于 2016-04-06T16:34:59.917 に答える
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)
于 2015-04-01T20:32:15.980 に答える