Django Testing - check messages for a view that redirects
Use the follow=True
option in the client.get()
call, and the client will follow the redirect. You can then test that the message is in the context of the view you redirected to.
def test_some_view(self): # use follow=True to follow redirect response = self.client.get('/some-url/', follow=True) # don't really need to check status code because assertRedirects will check it self.assertEqual(response.status_code, 200) self.assertRedirects(response, '/some-other-url/') # get message from context and check that expected text is there message = list(response.context.get('messages'))[0] self.assertEqual(message.tags, "success") self.assertTrue("success text" in message.message)
You can use get_messages() with response.wsgi_request like this (tested in Django 1.10):
from django.contrib.messages import get_messages ...def test_view(self): response = self.client.get('/some-url/') # you don't need follow=True self.assertRedirects(response, '/some-other-url/') # each element is an instance of django.contrib.messages.storage.base.Message all_messages = [msg for msg in get_messages(response.wsgi_request)] # here's how you test the first message self.assertEqual(all_messages[0].tags, "success") self.assertEqual(all_messages[0].message, "you have done well")
If your views are redirecting and you use follow=true
in your request to the test client the above doesn't work. I ended up writing a helper function to get the first (and in my case, only) message sent with the response.
@classmethoddef getmessage(cls, response): """Helper method to return message from response """ for c in response.context: message = [m for m in c.get('messages')][0] if message: return message
You include this within your test class and use it like this:
message = self.getmessage(response)
Where response
is what you get back from a get
or post
to a Client
.
This is a little fragile but hopefully it saves someone else some time.