So attempting to simulate a user login for a unit test has been driving me crazy for about the last hour or so. Django offers a pretty sweet testing client that simulates the http request/response model allowing for fairly robust unit tests to be built around the application views themselves. I was admittedly skeptical of unit testing views, but given the context I’ve become a believer. But on that note, keep in mind that they are still unit tests, they are not a replacement for Integration or User Acceptance tests.
As such I was a very happy camper until I began writing a test for a view that used the request.user.id value of a logged in user. Of course to test the functional part of the view it checked if a user was logged in (request.user.id != null), and if null would skip processing. Well, that doesn’t do me any good. I needed to convince the view that I am logged in.
So I went through the ropes of using the RequestFactory and the User model to create a fake request with a simulated user. While this worked, there were still session issues. I’ll also note that I found very little on the web about simulating user authentication in unit tests which surprised me since django documentation has never been something I’ve had trouble finding.
Eventually, I discovered a login() method in the Client model. It accepts a username and password and performs the login without requiring the request like the login() method in the ‘auth’ module. Keep in mind that the primary database is not used in unit tests, so an empty replica is used. As such you will need to create the mock user at runtime.
So I’ll wrap up with a working example of the code. Enjoy.
from django.test import TestCase
from django.test.client import Client
from django.contrib.auth.models import User
class ViewsTestCase(TestCase):
def setUp(self):
self.client = Client()
def test_MyView(self):
User.objects.create_user('fakename', 'fake@pukkared.com', 'mypassword')
#use test client to perform login
user = self.client.login(username='fakename', password='mypassword')
response = self.client.post('/myViewUrlPath/')
At Monserrate Monastery in Bogotá, Colombia.