Question

I'm trying to test the content of messages while processing ModelForms with Django. I've got the following View (assume there's a Thing model with a required name field):

@login_required
def update(request, thing_id):
    thing = Thing.objects.get(id=thing_id)  # assume this works

    if request.method == "POST":
        form = ThingModelForm(request.POST, instance=thing)
        if form.is_valid():
            form.save()
            messages.success(request, "Success!")
            return redirect("/wherever")
        else:
            messages.error(request, "Oops!")
    else:
        form = ThingModelForm(instance=thing)

    args = ("myapp/update.html", {"form": form})
    kwargs = {"context_instance": RequestContext(request)}
    return render_to_response(*args, **kwargs)

Now, I've got two unit tests. The first tests valid data, while the second tests invalid data. (Note that client login happens during setUp):

def test_update_account(self):
    url = reverse('update', args=[1])  # assume that's a valid id
    resp = self.client.post(url, {"name": "foo"})
    self.assertEqual(resp.status_code, 302)

    m = resp.cookies.get('messages', '')
    self.assertTrue("Success!" in m.output())

And now to test invalid data:

def test_update_account_failure(self):
    url = reverse('update', args=[1])  # assume that's a valid id
    resp = self.client.post(url, {"name": ""})  # name is required
    self.assertEqual(resp.status_code, 200)

    # This works:
    self.assertTrue("Oops!" in resp.content)

    # This fails:
    m = resp.cookies.get('messages', '')
    self.assertTrue("Oops!" in m.output())

Why would accessing the message's content through the cookie work in one instance but fail in another?

Was it helpful?

Solution

Two things you could check:

  1. When you create the request self.client.post(url, {"name": ""}) is a Thing instance returned here: thing = Thing.objects.get(id=thing_id) If not it will not reach the line of code where you set your error message: messages.error(request, "Oops!") as Thing.objects.get will throw an error.

If there are no results that match the query, get() will raise a DoesNotExist exception.

  1. If the first thing does return a Thing instance, you could check whether a redirect return redirect("/wherever") after setting the error message messages.error(request, "Oops!") does change anything.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top