Ошибка целостности побочного эффекта исправления Django не возникает

#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)