如何为受身份验证保护的 REST API 编写 Django 单元测试?
How to write Django Unit Test for Authentication Protected REST APIs?
我在 SO 上查看了两个答案,它们可能已经有了我的答案,但坦率地说,我只是不理解它们。这些 SO post 是: and .
两个 SO 问题使用不同的方法。
我尝试使用的方法是这样的。我创建了这个 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='mister_neutron@example.com',
password='F4kePaSs0d')
super(RemoteAuthenticatedTest, self).setUp()
我的单元测试是这样的:
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)
我的 settings.py 文件中有这个:
#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',
),
}
当我 运行 我的测试得到这个结果:
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
我做错了什么?
更新:在遵循@henriquesalvaro 明智的建议后,我将我的代码更新为:
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='mister_neutron@example.com',
password='F4kePaSs0d')
Token.objects.create(user=self.user)
super(RemoteAuthenticatedTest, self).setUp()
我将测试用例更新为:
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)
现在我的单元测试通过了。
在遵循@henriquesalvaro(见评论)的明智建议后,我已将我的代码更新为:
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='mister_neutron@example.com',
password='F4kePaSs0d')
Token.objects.create(user=self.user)
super(RemoteAuthenticatedTest, self).setUp()
我将测试用例更新为:
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)
现在我的单元测试通过了。
我在 SO 上查看了两个答案,它们可能已经有了我的答案,但坦率地说,我只是不理解它们。这些 SO post 是:
两个 SO 问题使用不同的方法。
我尝试使用的方法是这样的。我创建了这个 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='mister_neutron@example.com',
password='F4kePaSs0d')
super(RemoteAuthenticatedTest, self).setUp()
我的单元测试是这样的:
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)
我的 settings.py 文件中有这个:
#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',
),
}
当我 运行 我的测试得到这个结果:
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
我做错了什么?
更新:在遵循@henriquesalvaro 明智的建议后,我将我的代码更新为:
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='mister_neutron@example.com',
password='F4kePaSs0d')
Token.objects.create(user=self.user)
super(RemoteAuthenticatedTest, self).setUp()
我将测试用例更新为:
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)
现在我的单元测试通过了。
在遵循@henriquesalvaro(见评论)的明智建议后,我已将我的代码更新为:
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='mister_neutron@example.com',
password='F4kePaSs0d')
Token.objects.create(user=self.user)
super(RemoteAuthenticatedTest, self).setUp()
我将测试用例更新为:
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)
现在我的单元测试通过了。