#python #django #mocking
#python #django #издевательство
Вопрос:
У меня есть следующее представление, которое исключает запросы POST и сериализует данные объектов (Draftschedule) для создания новой копии (FrozenSchedule):
from reports.tasks import create_frozen_schedule
def freeze_schedule(request, pk):
"""Valid post request will freeze a Draft Schedule serializing its data"""
client = get_object_or_404(Client, draftschedule=pk)
try:
# Serialize data into a FrozenSchedule object
frozenschedule = create_frozen_schedule(pk, request.user.id)
except IntegrityError:
# Warn user if action failed
messages.warning(request, "A Schedule of this Type already exists")
return redirect(client.draftschedule)
else:
# If Schedule is Frozen successfully
messages.success(request, "Schedule Frozen")
return redirect(frozenschedule)
Я пытаюсь написать тест, чтобы утверждать, что определенные вещи происходят после возникновения ошибки целостности. Я изо всех сил пытаюсь понять, почему он терпит неудачу, мне не сразу понятно, где я ошибаюсь, поскольку я довольно неопытен в издевательствах / исправлениях.
Я пытался издеваться над create_frozen_schedule
функцией, чтобы вызвать IntegrityError при вызове:
def setUp(self):
self.url = reverse(
'reports:draftschedule-freeze',
args=[self._client.draftschedule.pk]
)
super(TestFreezeSchedule, self).setUp()
@patch('reports.tasks.create_frozen_schedule')
def test_freeze_schedule_with_conflict(self, mock_freeze):
mock_freeze.side_effect = IntegrityError
with self.assertRaises(IntegrityError):
self.client.post(self.url)
# More unit tests following same premise...
Но в итоге я получаю следующую ошибку:
.......................................................................................F............
======================================================================
FAIL: test_freeze_schedule_with_conflict (reports.tests.test_views.TestFreezeSchedule)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3.4/unittest/mock.py", line 1136, in patched
return func(*args, **keywargs)
File "/home/jwe/piesup2/reports/tests/test_views.py", line 495, in test_freeze_schedule_with_conflict
self.client.post(self.url)
AssertionError: IntegrityError not raised
----------------------------------------------------------------------
Примечания к сведению:
- Я могу воспроизвести эту ошибку вне тестов на моем реальном сайте Django.
- Я намеренно опустил
create_frozen_schedule
код, поскольку сериализация довольно многословна, и, насколько я понимаю, детали реализации в любом случае не должны иметь значения, поскольку я издеваюсь над функцией. -
Цель самой ошибки целостности — предотвратить дублирование
FrozenSchedule
объектов, мета-класс которых выглядит следующим образом:class Meta: # ... unique_together = ('client', 'data',)
Есть идеи, почему побочный эффект не возникает?
Ответ №1:
Ваше представление улавливает IntegrityError и возвращает перенаправление. Сообщение клиента, которое вызывает ваш тест, вообще не выдает ошибку.
Скорее, вы должны проверять, выполняются ли действия в блоке except: установлено ли предупреждение и перенаправляет ли сообщение на черновое расписание вместо замороженного.
Ответ №2:
Если вы хотите действительно проверить, что ваша функция выдает исключение, вам нужно протестировать функцию напрямую, а не через POST. Что-то вроде:
from django.test import RequestFactory
@patch('reports.tasks.create_frozen_schedule')
def test_freeze_schedule_with_conflict(self, mock_freeze):
mock_freeze.side_effect = IntegrityError
myrequest = RequestFactory().post(*some_url*)
# you may need to add, e.g., items to myrequest.POST
with self.assertRaises(IntegrityError):@patch('reports.tasks.create_frozen_schedule')
freeze_schedule(myrequest, pk)