在 Django Rest Framework 中测试对经过身份验证的路由的 POST 请求
To test a POST request for an authenticated route in Django Rest Framework
我想测试 post 对需要身份验证的路由的请求(来自 Django Rest Framework 的 Knox)。这里的 post 请求应该反对登录用户。
以下是urls.py
path('cards', addCard.as_view(), name="cards"),
以下是addCard视图
class addCard(generics.ListCreateAPIView):
serializer_class = CardSerializer
permission_classes = [permissions.IsAuthenticated, IsOwnerOrNot]
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
card = serializer.save(owner=self.request.user)
return Response({'card': CardSerializer(card, context=self.get_serializer_context()).data,})
def get_queryset(self):
return self.request.user.cards.order_by('-id')
下面是测试用例,我用了this answer,得到401!=201错误,明显是未授权用户。
class addCardAPIViewTestCase(APITestCase):
url = reverse("cards")
def setUp(self):
self.username = "john"
self.email = "john@snow.com"
self.password = "you_know_nothing"
self.user = get_user_model().objects.create_user(self.username,
self.password)
self.token = Token.objects.create(user=self.user)
def test_create_cards(self):
client = APIClient()
client.login(username=self.username,
password=self.password)
client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key)
response = client.post(self.url,{
"bank": "Citibank",
"card_number": "5618073505538298",
"owner_name": "c1",
"cvv": "121",
"expiry_date_month": "03",
"expiry_date_year": "2023"
},format='json')
self.assertEqual(response.status_code, 201)
如果要测试经过身份验证的用户,可以使用 client.login
或 client.credentials
。如果您通过 rest_framework.authentication.SessionAuthentication
对用户进行身份验证(也可以考虑 client.force_login
以获得更好的性能),则应使用第一个,第二个用于令牌身份验证。两者同时使用是没有意义的
使用client.force_authenticate(...)
class addCardAPIViewTestCase(APITestCase):
# Rest of your code
def test_create_cards(self):
<b>self.client.force_authenticate(self.user)</b>
response = <b>self.client.post</b>(self.url, {
"bank": "Citibank",
"card_number": "5618073505538298",
"owner_name": "c1",
"cvv": "121",
"expiry_date_month": "03",
"expiry_date_year": "2023"
}, format='json')
self.assertEqual(response.status_code, 201)
我想测试 post 对需要身份验证的路由的请求(来自 Django Rest Framework 的 Knox)。这里的 post 请求应该反对登录用户。
以下是urls.py
path('cards', addCard.as_view(), name="cards"),
以下是addCard视图
class addCard(generics.ListCreateAPIView):
serializer_class = CardSerializer
permission_classes = [permissions.IsAuthenticated, IsOwnerOrNot]
def post(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
card = serializer.save(owner=self.request.user)
return Response({'card': CardSerializer(card, context=self.get_serializer_context()).data,})
def get_queryset(self):
return self.request.user.cards.order_by('-id')
下面是测试用例,我用了this answer,得到401!=201错误,明显是未授权用户。
class addCardAPIViewTestCase(APITestCase):
url = reverse("cards")
def setUp(self):
self.username = "john"
self.email = "john@snow.com"
self.password = "you_know_nothing"
self.user = get_user_model().objects.create_user(self.username,
self.password)
self.token = Token.objects.create(user=self.user)
def test_create_cards(self):
client = APIClient()
client.login(username=self.username,
password=self.password)
client.credentials(HTTP_AUTHORIZATION='Token ' + self.token.key)
response = client.post(self.url,{
"bank": "Citibank",
"card_number": "5618073505538298",
"owner_name": "c1",
"cvv": "121",
"expiry_date_month": "03",
"expiry_date_year": "2023"
},format='json')
self.assertEqual(response.status_code, 201)
如果要测试经过身份验证的用户,可以使用 client.login
或 client.credentials
。如果您通过 rest_framework.authentication.SessionAuthentication
对用户进行身份验证(也可以考虑 client.force_login
以获得更好的性能),则应使用第一个,第二个用于令牌身份验证。两者同时使用是没有意义的
使用client.force_authenticate(...)
class addCardAPIViewTestCase(APITestCase):
# Rest of your code
def test_create_cards(self):
<b>self.client.force_authenticate(self.user)</b>
response = <b>self.client.post</b>(self.url, {
"bank": "Citibank",
"card_number": "5618073505538298",
"owner_name": "c1",
"cvv": "121",
"expiry_date_month": "03",
"expiry_date_year": "2023"
}, format='json')
self.assertEqual(response.status_code, 201)