pythondjangotestingposthttp-status-code-404

Django Test Client post() returns 302 despite error on view's post()


I'm currently writing up some basic tests to ensure pages in a medium sized Django application are GETting and POSTing correctly. However, using django.test.client.Client isn't reliably failing when it should be. It returns a 302 response even when there's obviously placed errors in my code.

in my app/urls.py:

url(r'^mymodel/create/$', 
views.MyModelView.as_view(),
name = 'my_model_create'),

Then, in attempts to intentionally create a 500 response, I did the following:

class MyModelCreateView(MyModelView, CreateView):

    def post(self, request, *args, **kwargs):
        print self.hello
        self.object = MyModel()
        return super(MyModelCreateView, self).post(request, *args, **kwargs)

Obviously, the view doesn't have any object called hello. This fails as expected when trying to send the request through the browser.

and even went as far as replacing "print self.hello" with

return HttpResponse(status = 500)

and yet, I still get the following:

#We have a model called Client, so it 
#is imported as RequestClient to avoid conflicts
In [1]: from django.test.client import Client as RequestClient

In [2]: client = RequestClient()

In [3]: response = client.post("/app/mymodel/create/")

In [4]: response.status_code
Out[4]: 302

Clearly the problem here is between the keyboard and the chair, since there's no reason Client()/RequestClient() shouldn't return a 500 error if done correctly. Even some problems arise as I receive 302 responses for POST requests instead of 200 responses, but that may be because we're using HttpRedirect.

Does anyone out there know what may be the problem here? For reference I'm on Python 2.7 and Django 1.5 (though I may need to be compatible with Django 1.4).


Solution

  • It's not totally clear why you're getting a redirect, but if you want to follow it you need to tell RequestClient to follow redirects - per the documentation:

    If you set follow to True the client will follow any redirects and a redirect_chain attribute will be set in the response object containing tuples of the intermediate urls and status codes.

    So your test code should look like:

    response = client.post("/app/mymodel/create/", follow=True)
    

    It'd be worth checking the request chain to see where exactly it was routed.