我正在使用Django测试客户端django.test.client.Client
来测试Django应用程序中的一些视图。特别是,我正在测试一个视图调用get_object_or_404
方法并且该对象不存在的情况,因此应返回404。
我的测试代码如下:
class ViewTests(TestCase):
fixtures=['test.json']
def test_thing_not_there_get(self):
url = '/foo/30afda98-b9d7-4e26-a59a-76ac1b6a001f/'
c = django.test.client.Client()
response = c.get(url)
self.assertEqual(response.status_code, 404)
但是,我得到的是视图代码中未处理的异常错误:
python projects/unittests/manage.py test
Creating test database for alias 'default'...
......ERROR:root:Unhandled Exception on request for http://testserver/foo/30afda98-b9d7-4e26-a59a-76ac1b6a001f/
Traceback (most recent call last):
File "/Users/lorin/.virtualenvs/myvenv/lib/python2.7/site-packages/django/core/handlers/base.py", line 111, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "/Users/lorin/.virtualenvs/myvenv/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 39, in wrapped_view
resp = view_func(*args, **kwargs)
File "/Users/lorin/.virtualenvs/myvenv/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 52, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/lorin/django-myvenv/apps/myvenv_desktop/views.py", line 85, in foo_view
instance = get_object_or_404(Foo, uuid=foo_uuid)
File "/Users/lorin/.virtualenvs/myvenv/lib/python2.7/site-packages/django/shortcuts/__init__.py", line 115, in get_object_or_404
raise Http404('No %s matches the given query.' % queryset.model._meta.object_name)
Http404: No Foo matches the given query.
测试客户端看不到的唯一例外是 Http404,PermissionDenied和SystemExit。 Django抓住了这些 内部异常并将它们转换为适当的HTTP 响应代码。在这些情况下,您可以检查response.status_code 你的考试。
为什么Django在这种情况下不会捕获Http404异常?
请注意(符合文档),不被抛入测试客户端。如果我试图在客户端捕获异常:
with self.assertRaises(django.http.Http404):
response = c.get(url)
我得到了同样的错误,还有一个额外的错误:
AssertionError: Http404 not raised
答案 0 :(得分:6)
我知道这是前一段时间,但我解决了这个问题,所以我觉得值得分享。您需要做的是在代码中自定义错误处理程序。例如,我有:
在urls.py中:
from myapp.views import error_handler
handler404 = error_handler.error404
和函数error404:
from django.http import HttpResponseNotFound
def error404(request):
t = loader.get_template('404.html')
html = t.render(Context())
return HttpResponseNotFound(html)
如果发送HttpResponseNotFound
对象,则会将其解释为404状态代码。
修改强>
在较新版本的django中,只需将404.html
放在templates目录中即可。只有在需要更多逻辑而不仅仅显示错误页面时,才需要上述控制器。
答案 1 :(得分:2)
进一步检查后,看起来测试按照书面传递:错误消息实际上并不对应于测试失败。