I have a BaseTestCase
class for base set up.
Let me show you the problem:
class UserTestCase(BaseTestCase):
def test_auth_login(self):
self.client.logout()
url = "/auth/login/"
body = {
"email": self.user_1.email,
"password": "12345678"
}
is_true = self.user_1.check_password("12345678")
print("password: ", is_true) # OUTPUT : password: True
response = self.client.post(url, data=body)
print(response) OUTPUT: {"error": "Given credentials are wrong."}
self.assertEqual(response.status_code, 200) # FALSE ERROR
And this is my view:
class AuthToken(ObtainAuthToken):
@extend_schema(
request=serializers.LoginSerializer,
responses={200: serializers.TokenSerializer, 400: DefaultExceptionSerializer},
)
def post(self, request, *args, **kwargs):
serializer = serializers.LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
email = serializer.validated_data["email"] # type: ignore
password = serializer.validated_data["password"] # type: ignore
user = authenticate(username=email, password=password)
if user:
token, created = Token.objects.get_or_create(user=user)
return Response({"token": token.key}, status=status.HTTP_200_OK)
return Response({"error": "Given credentials are wrong."}, status=status.HTTP_400_BAD_REQUEST)
User variable is coming None and my view is returning error.
I don't understand why authenticate(username=email, password=password)
is coming None.
Its working very well on "runserver".
Additional Information: I override user model. In my settings.py I have
AUTH_USER_MODEL = "UserAuth.User"
and I don't know is that important but I also have this in my settings.py:
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql_psycopg2",
"NAME": env("DB_NAME"),
"USER": env("DB_USER"),
"PASSWORD": env("DB_PASSWORD"),
"HOST": env("DB_HOST"),
"PORT": env.int("DB_PORT"),
},
'test': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'test_db.sqlite3',
}
}
TEST_RUNNER = 'django.test.runner.DiscoverRunner'
I know authenticate is not working because
is_true = self.user_1.check_password("12345678")
print("test_auth true", is_true)
is coming True
The error you are getting is not from authenticate. The issue is because the user requesting to login is not registered.
You must first create a .setUp()
method to register the user before you can test the login.
This is a a better way of how you can write your testcase:
from rest_framework.test import APITestCase
class UserTestCase(APITestCase):
def setUp(self):
self.user = User.objects.create_user(email="[email protected]", password="12345678") # Create a user
def test_auth_login(self):
url = "/auth/login/" # Better use named urls instead of hardcoded urls
body = {
"email": "[email protected]",
"password": "12345678"
}
response = self.client.post(url, data=body)
self.assertEqual(response.status_code, 200)
Remember to include any required fields when creating a user.
My recommendation: