4

I have been referring to the tutorial in https://developer.mozilla.org/en-US/docs/Learn/Server-side/Django/Testing when working on my own unit testing. My unit test codes are below:

from django.core.urlresolvers import reverse
from django.test import Client, TestCase
from django.contrib.auth.models import User

from companies.models import Company

class ContactViewTest(TestCase):

    def setUp(self):
        self.client = Client(HTTP_HOST='localhost:8000')

        company = Company(name='Test')
        company.save()

        user = User.objects.create(username='test_user1', email='test_user1@test.com')
        user.set_password('password')
        user.save()

        self.user = user
        self.company = company

    def test_logged_in_all_contacts_correct_template(self):
        c = self.client
        user_login = c.login(username=self.user.username, password=self.user.password)
        self.assertTrue(user_login)

        resp = c.get(reverse('all-contacts'), follow=True)

        # Check if user is logged in
        self.assertEquals(str(resp.context['user']), 'test_user1')
        # Check if response is "success"
        self.assertEqual(resp.status_code, 200)

        self.assertTemplateUsed(resp, 'all_contacts.html')

Upon running python manage.py test contacts.tests, I ran into a few errors.

The first being self.assertTrue(user_login) which returns AssertionError: False is not true

The second being self.assertEquals(str(resp.context['user']), 'test_user1') which returns AssertionError: 'AnonymousUser' != 'test_user1' when I removed self.assertTrue(user_login)

I am not really sure what went wrong other than the client.login() did not work as I expected so thanks in advance to whoever can help.

chronox
  • 117
  • 1
  • 14

2 Answers2

4

The problem is that self.user.password is the hashed password.

You can either do,

user_login = c.login(username=self.user.username, password='password')

or you could use force_login instead, which doesn't require a password.

c.force_login(self.user)
Alasdair
  • 298,606
  • 55
  • 578
  • 516
  • I tried user_login = c.login(username=self.user.username, password='password'), but still could got AssertionError: False is not true. As I am using django 1.8.5 and could not change it, there is no force_login for me to use – chronox May 06 '18 at 05:26
  • I can’t spot any other issues in the code you have posted. [This answer](https://stackoverflow.com/a/34775790/) suggests to check your installed apps/middleware, but the default settings should work. Note that Django 1.8.x is end of life and does not receive security fixes, you should upgrade. Even if you can’t upgrade to 1.11 LTS or 2.0 immediately you should upgrade to the latest 1.8.x - you are missing out over two years of security fixes. – Alasdair May 06 '18 at 07:12
1

Any case from the following can be possible:

Make sure you are using the correct DJANGO_SETTINGS_MODULE.

Following apps should be listed in INSTALLED_APPS:

INSTALLED_APPS = (
    ...,
    'django.contrib.auth',
    'django.contrib.sessions'
    ..,
    )

Following middlewares should be listed in MIDDLEWARE:

MIDDLEWARE = (
    ...,
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    ...,
    )

If you have swapped the django.contrib.auth.models.User with a custom User my_app.User then tests require you have my_app listed in INSTALLED_APPSand also AUTH_USER_MODEL i.e

INSTALLED_APPS = (
...,
    'my_app',
..,
)
AUTH_USER_MODEL = 'my_app.User'
Abdullah
  • 93
  • 14
  • Why should CsrfViewMiddleware be in middleware for login? What if we disabled Csrf? – kevr Dec 30 '22 at 22:07