Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit Testing Django Rest Framework Authentication at Runtime

I basically want to turn TokenAuthentication on but only for 2 unit tests. The only option I've seen so far is to use @override_settings(...) to replace the REST_FRAMEWORK settings value.

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

This isn't working. I can print the settings before and after the decorator and see that the values changed but django doesn't seem to be respecting them. It allows all requests sent using the test Client or the DRF APIClient object through without authentication. I'm getting 200 responses when I would expect 401 unauthorized.

If I insert that same dictionary into my test_settings.py file in the config folder everything works as expected. However like I said I only want to turn on authentication for a couple of unit tests, not all of them. My thought is that Django never revisits the settings for DRF after initialization. So even though the setting values are correct they are not used.

Has anyone run into this problem and found a solution? Or workaround?

like image 845
Rob Carpenter Avatar asked Mar 31 '15 10:03

Rob Carpenter


1 Answers

The following workaround works well for me:

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
like image 56
0x2207 Avatar answered Oct 11 '22 16:10

0x2207