Тестирование ожидаемого 404 с тестовым клиентом Django приводит к необработанному исключению
Я использую тестовый клиент 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.
по словам Django 1.3 docs
только исключения, которые не видны тестовому клиенту: Http404, PermissionDenied и SystemExit. Джанго ловит эти исключения внутренне и преобразует их в соответствующий HTTP код ответа. В этих случаях можно проверить ответ.status_code в ваш тест.
почему Django не ловит исключение Http404 в этом случае?
обратите внимание, что (в соответствии с документами), исключение не будучи брошеной в тест клиент. Если я попытаюсь поймать исключение на стороне клиента:
with self.assertRaises(django.http.Http404):
response = c.get(url)
Я получаю ту же ошибку, а также дополнительная погрешность:
AssertionError: Http404 not raised
2 ответов
Я знаю, что это было давно, но я решил это, поэтому я решил, что стоит поделиться. Что вам нужно сделать, это настроить обработчик ошибок в коде. Например, у меня есть:
in 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
в шаблонах справочник. Вышеуказанный контроллер необходим только в том случае, если вам нужно больше логики, чем просто отображение страницы ошибки.
при дальнейшей проверке похоже, что тест проходит как написано: сообщение об ошибке на самом деле не соответствует сбою теста.