While testing a Django DRF application, how can I make the user in my tests superuser?

981 Views Asked by At

I currently have a Django Rest Framework application that executes different logic for superusers than regular users. I've written my tests using both rest_framework.test and pytest-django. My Tests are currently failing because of the error: TypeError: Cannot cast AnonymousUser to int. Are you trying to use it in place of User?. So because I don't have a user set (my app does not allow unauthenticated users), my code is trying to look for a profile of the user making the call and failing.

Right now, I'm not looking to test the functionality of User logic. Is there a way to set the default user in test_settings.py to a superuser, or setup a superuser in the def setup(self, request) function at the start of each of my test classes?

The DRF docs relating to authentication in testing seem to be geared towards testing the authentication itself as opposed to assuming authentication around other tests. Based on those docs, I think I could hack something together, but there must be a standard way of doing what I'm trying.

From what I've read, I can use force_authenticate on a particular user, but it's unclear to me where that user comes from. Do I need to populate the DB with a superuser for testing before hand, or is there a way (preferably) to create a superuser on the fly?

Help is most appreciated :)

1

There are 1 best solutions below

1
On

Django creates (and then deletes) a new database on the fly each time you run tests. You don't need to populate the database before tests, simply create a new user in the test code each time you need one. For example:

from rest_framework.test import force_authenticate, APITestCase, APIRequestFactory
from rest_framework.authtoken.models import Token

class Test(APITestCase):
   def setUp(self):
      self.factory = APIRequestFactory()
      # If the user must be a superuser use User.objects.create_superuser instead of create_user 
      self.user = User.objects.create_user(username='test', first_name='test', last_name='test', email='[email protected]', password='Test1234')

   def test_example():
      request = self.factory.get(path='example/') # You can obtain the request in another way

      force_authenticate(request, self.user)

      # If you need a token use this instead:
      force_authenticate(request, self.user, 
Token.objects.get_or_create(user=self.user))