Question

I've got a Django view with a form, which I'm POSTing to in a unit test. Here's the general structure of the test:

class ViewTests(TestCase):
    form_url = reverse_lazy('myapp:form')
    success_url = reverse_lazy('myapp:success')

    def test_form_submission_with_valid_data_creates_new_object_and_redirects(self):
        attributes = EntryFactory.attributes()
        attributes['product'] = ProductFactory()  # Entry has a ForeignKey to Product
        response = self.client.post(self.form_url, attributes, follow=True)
        self.assertEqual(response.status_code, 200)
        self.assertRedirects(response, self.success_url)
        self.assertTemplateUsed(response, 'myapp/success.html')

However, I can't seem to figure out why the redirect isn't working as expected. I've tried dropping in a import pdb; pdb.set_trace() to see if there are any form errors (response.context['form'].errors), but all I get back is an empty dict. Submitting the form in the browser redirects properly, so I'm not sure why the unit test is failing, and also not sure how to debug it properly since no errors are showing up in the form error dict.

Was it helpful?

Solution

Turns out there were a few things wrong.

First, there was actually a second form on the page (for selection of Product) that I missed. Relatedly, I should have assigned ProductFactory().id to attributes['product'], rather than ProductFactory.

Second, after I changed that bit, there was an issue with the assertRedirects; I had to change self.success_url to unicode(self.success_url) since assertRedirects can't perform a comparison with a proxy.

Final product:

def test_form_submission_with_valid_data_create_new_entry_and_redirects(self):
    attributes = EntryFactory.attributes()
    attributes['product'] = ProductFactory().id
    response = self.client.post(self.form_url, attributes)
    self.assertRedirects(response, unicode(self.success_url))
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top