I have looked at two answers on SO that may already have my answer but frankly I just don't understand them. These SO post are: Django Rest Framework API Authentication Test and Django authenticate unit test.
Both of the SO questions use different approaches.
The approach I am attempting to use is this. I have created this class:
from rest_framework.test import APIClient from django.test import testcases from django.contrib.auth.models import User class RemoteAuthenticatedTest(testcases.TestCase): client_class = APIClient def setUp(self): self.username = 'mister_neutron' self.user = User.objects.create_user(username='mister_neutron', email='[email protected]', password='F4kePaSs0d') super(RemoteAuthenticatedTest, self).setUp() My unit test looks like this:
class InfoViewTestCase(RemoteAuthenticatedTest): def create_info_record(self): from random import randint blade = 'test-blade-host-name-%s' % (randint(0, 100)) breachs = randint(0,100) dimm = 'test dimm slot %s' % (randint(0,100)) url = reverse('info:info_creat') data = { 'blade_hostname': blade, 'breach_count': breachs, 'dimm_slot': dimm, } response = self.client.post(url, data, format='json', REMOTE_USER=self.username) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Info.objects.count(), 1) self.assertEqual(Info.objects.get().blade_hostname, blade) I have this in my settings.py file:
#Authentications REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', 'rest_framework.authentication.TokenAuthentication', ), 'DEFAULT_PERMISSION_CLASSES': ( 'rest_framework.permissions.IsAuthenticated', ), } When I run my test I get this result:
Failure Traceback (most recent call last): File "/myproject/info/tests.py", line 686, in create_info_record self.assertEqual(response.status_code, status.HTTP_201_CREATED) AssertionError: 401 != 201 What am I doing wrong?
UPDATE: After following @henriquesalvaro sage advice I have updated my code to this:
from rest_framework.test import APIClient,APITestCase from django.contrib.auth.models import User from rest_framework.authtoken.models import Token class RemoteAuthenticatedTest(APITestCase): client_class = APIClient def setUp(self): self.username = 'mister_neutron' self.user = User.objects.create_user(username='mister_neutron', email='[email protected]', password='F4kePaSs0d') Token.objects.create(user=self.user) super(RemoteAuthenticatedTest, self).setUp() And I updated my test case to this:
class InfoViewTestCase(RemoteAuthenticatedTest): def create_info_record(self): from random import randint blade = 'test-blade-host-name-%s' % (randint(0, 100)) breachs = randint(0,100) dimm = 'test dimm slot %s' % (randint(0,100)) url = reverse('info:info_creat') data = { 'blade_hostname': blade, 'breach_count': breachs, 'dimm_slot': dimm, } self.client.credentials(HTTP_AUTHORIZATION='Token ' + self.user.auth_token.key) response = self.client.post(url, data, format='json', REMOTE_USER=self.username) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Info.objects.count(), 1) self.assertEqual(Info.objects.get().blade_hostname, blade) And now my unit test passes.
rest_frameworkhas anAPITestCasewith the client already included, you can then override thesetUpmethod to create that classself.userand its token (Token.objects.create(user=self.user), for example). For your test functions you can then useself.client.credentials(HTTP_AUTHORIZATION='Token ' + self.user.auth_token.key)and make the requests as you wish.setUp()method? Do I define asetUp()method in myRemoteAuthenticatedTest()class and call it? How do I import the Token class?setUpand then add the credentials toself.clientbefore making the request it should work.Tokenclass?from rest_framework.authtoken.models import Tokenhopefully will do the trick!