Overriding DRF settings for tests

70 views Asked by At

I'm using Python 3.9, Django 3.2, DRF 3.12.4. I'm adding JWT authentication method using simple JWT. To test my auth method, I need to set

"DEFAULT_AUTHENTICATION_CLASSES": (
    "rest_framework_simplejwt.authentication.JWTAuthentication",
),

I would like to avoid editing my settings file and keep all changes in my test file. That's because I have separate local and production settings, and local settings are using fake auth backend. All tests are passing when I set the above auth class in my local settings.

I tried to use @override_settings:

@override_settings(
    REST_FRAMEWORK = {
        "DEFAULT_AUTHENTICATION_CLASSES": (
            "rest_framework_simplejwt.authentication.JWTAuthentication",
        ),
    }
)

It seems to work fine - when I print the settings in my test:

from django.conf import settings
from rest_framework.settings import api_settings

...

    def setUp(self):
        print(settings.REST_FRAMEWORK)
        print(api_settings.DEFAULT_AUTHENTICATION_CLASSES)

I get

{'DEFAULT_AUTHENTICATION_CLASSES': ('rest_framework_simplejwt.authentication.JWTAuthentication',)}
[<class 'rest_framework_simplejwt.authentication.JWTAuthentication'>]

However, tests aren't passing - I'm getting error from my fake auth backend, as if the settings aren't getting overriden after all. I also tried editing django.conf settings directly - which is something I would rather not do, but it didn't solve my problem as well. Am I doing something wrong? Maybe my solution/tests have some logical mistakes and I'm doing something I shouldn't do? Thank you in advance for all the help.

1

There are 1 answers

2
Dos On

An alternative solution is to directly modify the REST_FRAMEWORK settings in the test setup. This allows you to dynamically change the settings for the duration of the test case.

from django.conf import settings
from rest_framework.test import APITestCase

class MyTests(APITestCase):
    def setUp(self):
        # Modify REST_FRAMEWORK settings for JWT authentication in the setup
        settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = ["rest_framework_simplejwt.authentication.JWTAuthentication"]

    def tearDown(self):
        # Optionally reset modified settings in tearDown to avoid side effects
        settings.REST_FRAMEWORK['DEFAULT_AUTHENTICATION_CLASSES'] = original_authentication_classes

    def test_my_view(self):
        # Your test code here

Just be cautious with this method, as it directly modifies global settings and could potentially affect other tests or parts of your application. Always ensure that you reset any modified settings in the tearDown or tearDownClass methods to avoid unintended side effects.