I am testing my authentication with the django.test.Client
and two tests cases fail because once I test my test_login_success
test case, the other tests fail because the user remains authenticated, even when I am instantiating a new client in the class setUp
and even deleting the user in the tearDown
.
My code:
from django.test import Client, TestCase
from app.users.models import User
class TestLogin(TestCase):
def setUp(self):
super().setUp()
self.email = 'test@test.com'
self.password = 'SomeRandomPass96'
User.objects.create_user(email=self.email, password=self.password)
self.client = Client()
def tearDown(self):
User.objects.filter(email=self.email).delete()
super().tearDown()
def test_not_authenticated(self): # success the first time, fails after test_login_success is executed for the first time.
user = User.objects.get(email=self.email)
assert not user.is_authenticated
def test_login_success(self): # always success
self.client.post(
'/users/login/',
{'email': self.email, 'password': self.password}
)
user = User.objects.get(email=self.email)
assert user.is_authenticated
def test_login_wrong_credentials(self): # success the first time, fails after test_login_success is executed for the first time.
self.client.post(
'/users/login/',
{'email': self.email, 'password': 'wrongPassword123'}
)
user = User.objects.get(email=self.email)
assert not user.is_authenticated
The error: user.is_authenticated
is not doing what is expected in this code. Since the user in request
object in the view will be an AnonymousUser
or a User
instance depending on the case if it's authenticated and I was accessing directly to a User instance from the database.
The proper way is to access to the user from the request object, and since we don't have the view context in the test case, Django provides it returned in the response like so:
def test_not_authenticated(self):
response = self.client.get('')
user = response.wsgi_request.user
assert not user.is_authenticated