Django APIClient не работает
У меня проблемы с аутентификацией с помощью моего Django Rest Framework API в модульных тестах. Система работает должным образом при доступе к ней через браузер. Однако я получаю 401 HTTP-статус при отправке запроса на поставку в следующий класс в следующей конечной точке:
class UserDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
authentication_classes = (BasicAuthentication, TokenAuthentication)
permission_classes = IsAuthenticated,
queryset = CustomUser.objects.all()
serializer_class = UserSerializer
Тест ниже выглядит следующим образом:
class AccountTests(APITestCase):
def setUp(self):
self.user = CustomUser.objects.create_user(email="user1@test.com", password="password1", is_staff=True)
self.user.save()
self.user = CustomUser.objects.get(email="user1@test.com")
self.client = APIClient()
def test_add_name(self):
self.client.login(email="user1@test.com", password='password1')
url = reverse('customuser-detail', args=(self.user.id,))
data = {'first_name': 'test', 'last_name': 'user'}
self.client.login(email="user1@test.com", password='password1')
response = self.client.put(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)
При печати response.data я получаю:
{u'detail': u'Authentication credentials were not provided.'}
Метод client.login(...) возвращает true, но учетные данные не отображаются в заголовке. Мои эксперименты в классах разрешений IsAuthenticated имели request.user = AnonymousUser. В классе BasicAuthentication auth = Нет.
Я что-то упустил в отношении использования BasicAuth в settings.py? Или даже в самом тесте?
Благодарю.
2 ответа
Первый, {u'detail': u'Authentication credentials were not provided.'}
происходит, когда предоставленные вами учетные данные не соответствуют моделям. (Мне кажется это плохое сообщение об ошибке)
Итак, вы должны установить пароль пользователя set_password()
метод, из-за шифрования.
self.user = CustomUser.objects.create_user(email="user1@test.com", is_staff=True)
self.user.set_password("password1")
self.user.save()
или вы можете использовать force_login()
для тестирования.
self.client.force_login(
user=User.objects.first(),
backend='django.contrib.auth.backends.ModelBackend' # one of your AUTHENTICATION_BACKENDS
)
Вам может понадобиться использовать force_authenticate()
метод входа в систему,
def test_add_name(self):
self.client.force_authenticate(self.user)
........
Вы можете переписать свой тестовый пример, может быть, как-то так,
class AccountTests(APITestCase):
def setUp(self):
self.user = CustomUser.objects.create_user(email="user1@test.com", password="password1", is_staff=True)
self.client = APIClient()
def test_add_name(self):
self.client.force_authenticate(self.user)
url = reverse('customuser-detail', args=(self.user.id,))
data = {'first_name': 'test', 'last_name': 'user'}
response = self.client.put(url, data, format='json')
self.assertEqual(response.status_code, status.HTTP_200_OK)