首页 > 解决方案 > 不接受 Django 单元测试身份验证令牌

问题描述

我已经检查了 DRF 官方文档,阅读了以下帖子并从一些答案中复制粘贴代码以避免任何拼写错误,但我仍然无法在我的单元测试中进行身份验证。我总是收到 401 响应代码。

我有一个自定义用户模型,到目前为止只有几个不需要的字段。

任何人都可以看到代码中的任何逻辑问题或错误吗?问题是否源于拥有适当的本地数据库和测试数据库以及身份验证以某种方式混合在一起?

我不得不使用self.client.force_authenticate(user=self.user, token=None)绕过身份验证问题。但这违背了测试的目的。

已检查未解决问题的帖子:

所以这是我的代码。

单元测试

from django.test.testcases import SimpleTestCase
from django.urls import reverse, resolve
from rest_framework import status
from rest_framework.test import APITestCase
from rest_framework.authtoken.models import Token
from test_project.models.user import *
from test_project.views import UserViewSet
# from django.contrib.auth.models import User
from test_project.models import *


class UserAPIViewTests(APITestCase):

  def setUp(self) -> None:
    self.users_list_url = reverse('user-list')
    self.users_detail_url = reverse('user-detail', args=[1])
    self.user =User.objects.create(
      username="admin",
      password="admin",
      email="test@necktie.com",
      first_name="test first name",
      last_name="test last name",
      is_superuser=True,
      is_staff=True,
      is_active=True
    )
    self.token = Token.objects.create(user=user)
    self.client.credentials(HTTP_AUTHORIZATION='Bearer ' + self.token.key)

  # The testing DB is automatically torn down, no implementation required for those tests
  def tearDown(self) -> None:
    pass


  def test_get_users_authenticated(self):
    """
    Test that an authenticated user can get the users' list
    """
    response = self.client.get(self.users_list_url)
    self.assertEquals(response.status_code, status.HTTP_200_OK)

用户模型

from django.db import models
from django.contrib.auth.models import AbstractUser
from django.utils.translation import gettext_lazy as _

class User(AbstractUser):
  """auth/login-related fields"""
  gender = models.CharField(_('gender'), max_length=50, null=True)
  nationality = models.CharField(_('nationality'), max_length=50, null=True)


  def __str__(self):
    return "{} {}".format(self.first_name, self.last_name)

用户视图

from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import permissions
from ..models.user import User
from ..serializers.user import *
from ..permissions import *

class UserViewSet(viewsets.ModelViewSet):
  """
  This viewset automatically provides `list`, `create`, `retrieve`,
  `update` and `destroy` actions.
  """
  queryset = User.objects.all()
  serializer_class = UserSerializer

  def get_permissions(self):
    """
    Method to apply permissions depending on request type (GET, PUT etc.)
    """
    if self.request.method == 'GET':
      return [permissions.IsAuthenticated(), IsStaff()]
    else:
      return [permissions.IsAuthenticated(), IsSuperuser()]

用户序列化器

from rest_framework import serializers
from ..models.user import User


class UserSerializer(serializers.ModelSerializer):
  """
  Serializer for all actions on User model
  """

  class Meta:
    model = User
    fields = [
      'id',
      'username',
      'first_name',
      'last_name',
      'is_staff',
      'is_superuser',
      'is_active',
      'date_joined'
    ]

谢谢您的帮助!

标签: djangounit-testingauthenticationdjango-rest-framework

解决方案


推荐阅读