I have been writing tests for one of my django applications and have been looking to get around this problem for quite some time now. I have a view that sends messages using django.contrib.messages
for different cases. The view looks something like the following.
from django.contrib import messages
from django.shortcuts import redirect
import custom_messages
def some_view(request):
""" This is a sample view for testing purposes.
"""
some_condition = models.SomeModel.objects.get_or_none(
condition=some_condition)
if some_condition:
messages.success(request, custom_message.SUCCESS)
else:
messages.error(request, custom_message.ERROR)
redirect(some_other_view)
Now, while testing this view client.get
's response does not contain the context
dictionary that contains the messages
as this view uses a redirect. For views that render templates we can get access to the messages list using messages = response.context.get('messages')
. How can we get access messages
for a view that redirects?
Use the
follow=True
option in theclient.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.I had the same problem when using a 3rd party app.
If you want to get the messages from a view that returns an HttpResponseRedict (from which you can't access the context) from within another view, you can use
get_messages(request)
This clears the message storage though, so if you want to access the messages from a template later on, add:
Alternative method mocking messages (doesn't need to follow redirect):
You can use get_messages() with response.wsgi_request like this (tested in Django 1.10):
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.You include this within your test class and use it like this:
Where
response
is what you get back from aget
orpost
to aClient
.This is a little fragile but hopefully it saves someone else some time.