Fixed #3162 -- Added coded to catch and rethrow exceptions that are thrown by the views visited by the test client. Thanks, Ben <afternoon@uk2.net>.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@4482 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
23272de5db
commit
f9cdde0cb4
1
AUTHORS
1
AUTHORS
|
@ -53,6 +53,7 @@ answer newbie questions, and generally made Django that much better:
|
|||
Shannon -jj Behrens <http://jjinux.blogspot.com/>
|
||||
Esdras Beleza <linux@esdrasbeleza.com>
|
||||
James Bennett
|
||||
Ben <afternoon@uk2.net>
|
||||
Paul Bissex <http://e-scribe.com/>
|
||||
Simon Blanchard
|
||||
Andrew Brehaut <http://brehaut.net/blog>
|
||||
|
|
|
@ -4,6 +4,7 @@ from django.contrib.sites.models import Site
|
|||
from django.template import Context, loader
|
||||
from django.core import validators
|
||||
from django import oldforms
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
class UserCreationForm(oldforms.Manipulator):
|
||||
"A form that creates a user, with no privileges, from the given username and password."
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import sys
|
||||
from cStringIO import StringIO
|
||||
from django.conf import settings
|
||||
from django.core.handlers.base import BaseHandler
|
||||
from django.core.handlers.wsgi import WSGIRequest
|
||||
from django.core.signals import got_request_exception
|
||||
from django.dispatch import dispatcher
|
||||
from django.http import urlencode, SimpleCookie
|
||||
from django.test import signals
|
||||
|
@ -100,6 +102,14 @@ class Client:
|
|||
self.defaults = defaults
|
||||
self.cookies = SimpleCookie()
|
||||
self.session = {}
|
||||
self.exc_info = None
|
||||
|
||||
def store_exc_info(self, *args, **kwargs):
|
||||
"""
|
||||
Utility method that can be used to store exceptions when they are
|
||||
generated by a view.
|
||||
"""
|
||||
self.exc_info = sys.exc_info()
|
||||
|
||||
def request(self, **request):
|
||||
"""
|
||||
|
@ -128,6 +138,9 @@ class Client:
|
|||
on_template_render = curry(store_rendered_templates, data)
|
||||
dispatcher.connect(on_template_render, signal=signals.template_rendered)
|
||||
|
||||
# Capture exceptions created by the handler
|
||||
dispatcher.connect(self.store_exc_info, signal=got_request_exception)
|
||||
|
||||
response = self.handler(environ)
|
||||
|
||||
# Add any rendered template detail to the response
|
||||
|
@ -142,6 +155,11 @@ class Client:
|
|||
else:
|
||||
setattr(response, detail, None)
|
||||
|
||||
# Look for a signalled exception and reraise it
|
||||
if self.exc_info:
|
||||
raise self.exc_info[1], None, self.exc_info[2]
|
||||
|
||||
# Update persistent cookie and session data
|
||||
if response.cookies:
|
||||
self.cookies.update(response.cookies)
|
||||
|
||||
|
|
|
@ -291,6 +291,17 @@ for testing purposes:
|
|||
|
||||
.. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
||||
|
||||
Exceptions
|
||||
~~~~~~~~~~
|
||||
|
||||
If you point the Test Client at a view that raises an exception, that exception
|
||||
will be visible in the test case. You can then use a standard ``try...catch``
|
||||
block, or ``unittest.TestCase.assertRaises()`` to test for exceptions.
|
||||
|
||||
The only exceptions that are not visible in a Test Case are ``Http404``,
|
||||
``PermissionDenied`` and ``SystemExit``. Django catches these exceptions
|
||||
internally and converts them into the appropriate HTTP responses codes.
|
||||
|
||||
Persistent state
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -114,4 +114,14 @@ class ClientTest(unittest.TestCase):
|
|||
|
||||
# Check that the session was modified
|
||||
self.assertEquals(self.client.session['tobacconist'], 'hovercraft')
|
||||
|
||||
|
||||
def test_view_with_exception(self):
|
||||
"Request a page that is known to throw an error"
|
||||
self.assertRaises(KeyError, self.client.get, "/test_client/broken_view/")
|
||||
|
||||
#Try the same assertion, a different way
|
||||
try:
|
||||
self.client.get('/test_client/broken_view/')
|
||||
self.fail('Should raise an error')
|
||||
except KeyError:
|
||||
pass
|
||||
|
|
|
@ -6,5 +6,6 @@ urlpatterns = patterns('',
|
|||
(r'^post_view/$', views.post_view),
|
||||
(r'^redirect_view/$', views.redirect_view),
|
||||
(r'^login_protected_view/$', views.login_protected_view),
|
||||
(r'^session_view/$', views.session_view)
|
||||
(r'^session_view/$', views.session_view),
|
||||
(r'^broken_view/$', views.broken_view)
|
||||
)
|
||||
|
|
|
@ -36,11 +36,13 @@ login_protected_view = login_required(login_protected_view)
|
|||
|
||||
def session_view(request):
|
||||
"A view that modifies the session"
|
||||
|
||||
request.session['tobacconist'] = 'hovercraft'
|
||||
|
||||
t = Template('This is a view that modifies the session.',
|
||||
name='Session Modifying View Template')
|
||||
c = Context()
|
||||
return HttpResponse(t.render(c))
|
||||
|
||||
|
||||
def broken_view(request):
|
||||
"""A view which just raises an exception, simulating a broken view."""
|
||||
raise KeyError("Oops! Looks like you wrote some bad code.")
|
||||
|
|
Loading…
Reference in New Issue