登录测试期间身份验证失败

时间:2021-06-03 09:54:42

标签: django django-rest-framework pytest pytest-django

我正在尝试测试自定义登录(使用 pytest),但身份验证失败返回 None。 这是views.py

 (5,5), (21,14), (22,3), (22,7)

serializers.py

from rest_framework.authtoken.views import ObtainAuthToken
from my_auth.api.serializers import UserLoginSerializer

class LoginAuthToken(ObtainAuthToken):
    serializer_class = UserLoginSerializer

tests.py

from django.contrib.auth import authenticate
from django.utils.translation import gettext_lazy as _

from rest_framework import serializers
from rest_framework.authtoken.serializers import AuthTokenSerializer


class UserLoginSerializer(AuthTokenSerializer):
    username = None
    email = serializers.EmailField(
        label=_("Email"),
    )

    def validate(self, attrs):
        email = attrs.get('email')
        password = attrs.get('password')
        if email and password:
            user = authenticate(request=self.context.get('request'),
                                email=email, password=password)  # returns None

            if not user:
                msg = _('Unable to log in with provided credentials.')
                raise serializers.ValidationError(msg, code='authorization')  # raises
        else:
            msg = _('Must include "email" and "password".')
            raise serializers.ValidationError(msg, code='authorization')

        attrs['user'] = user
        return attrs

终端输出:

import pytest

from django.urls import reverse

from rest_framework import status
from rest_framework.authtoken.models import Token
from rest_framework.test import APIClient


@pytest.fixture
def test_user():
    user = MyUser.objects.create(
        email='test@m.com',
        first_name='Firstname',
        last_name='Lastname'
    )
    user.set_password('pass5678')
    return user


@pytest.mark.django_db
def test_login(test_user):
    client = APIClient()
    response = client.post(
        path=reverse('login'),
        data={
            'email': 'test@m.com',
            'password': 'pass5678',
        },
        format='json',
    )
    assert(response.status_code == status.HTTP_200_OK)
    token = Token.objects.get(user=test_user)
    assert(token.key == response.data['token'])

这是我在 test_login 中执行 ========================================================================================================== test session starts ========================================================================================================== platform linux -- Python 3.8.5, pytest-6.2.4, py-1.10.0, pluggy-0.13.1 django: settings: news_project.settings (from ini) rootdir: /home/andrei/NEWS/news_project, configfile: pytest.ini plugins: lambda-1.2.4, Faker-8.4.0, common-subject-1.0.5, assert-utils-0.2.2, drf-1.1.2, fixture-order-0.1.3, django-4.3.0 collected 2 items my_auth/tests.py F [ 50%] news/tests.py . [100%] =============================================================================================================== FAILURES ================================================================================================================ ______________________________________________________________________________________________________________ test_login _______________________________________________________________________________________________________________ test_user = <MyUser: test@m.com> @pytest.mark.django_db def test_login(test_user): client = APIClient() response = client.post( path=reverse('login'), data={ 'email': 'test@m.com', 'password': 'pass5678', }, format='json', ) > assert(response.status_code == status.HTTP_200_OK) E assert 400 == 200 E + where 400 = <Response status_code=400, "application/json">.status_code E + and 200 = status.HTTP_200_OK my_auth/tests.py:78: AssertionError ----------------------------------------------------------------------------------------------------------- Captured log call ----------------------------------------------------------------------------------------------------------- WARNING django.request:log.py:224 Bad Request: /api/auth/login/ ======================================================================================================== short test summary info ======================================================================================================== FAILED my_auth/tests.py::test_login - assert 400 == 200 ====================================================================================================== 1 failed, 1 passed in 3.63s ====================================================================================================== 时的输出

print(response.data)

起初我以为rest_framework.request.Request 对象没有传递给UserLoginSerializer 的validate(),但实际上它是。而且,它和我通过Postman发送POST请求时获得的Request几乎相同。我错过了什么?

1 个答案:

答案 0 :(得分:0)

您仍然需要在调用 save 后调用 set_password 用户:

@pytest.fixture
def test_user():
    user = MyUser.objects.create(
        email='test@m.com',
        first_name='Firstname',
        last_name='Lastname'
    )
    user.set_password('pass5678')
    user.save()
    return user

https://docs.djangoproject.com/en/3.2/ref/contrib/auth/#django.contrib.auth.models.User.set_password

<块引用>

将用户的密码设置为给定的原始字符串,处理密码散列。不保存 User 对象。

相关问题