Python call_command используется также и в других тестах - PullRequest
0 голосов
/ 15 октября 2018

Использование Django 1.10 и python 3.5.1.

Я пытаюсь смоделировать функцию 'call_command', чтобы вызвать исключение.Проблема в том, что кажется, что в тот момент, когда он получает функцию «side_effect», он действует и для других тестов.Что я делаю не так или как я могу «отменить» побочный эффект от этой функции?

В этом примере после выполнения одного из тестов все остальные тесты, которые будут выполняться позже, будут вызывать то же исключение, даже если это не так.должен выдать исключение в этом тесте.

 def test_run_migrations_raise_exception(self):

    with mock.patch('django.core.management.call_command', return_value=None, side_effect=Exception('e message')):
        self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)
        call_command('run_data_migrations')
        self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)

 def test_run_migrations_raise_flow_exception(self):

    with mock.patch('django.core.management.call_command', return_value=None, side_effect=FlowException(500, 'fe message', {'a': 1})):
        self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)
        call_command('run_data_migrations')
        self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)

1 Ответ

0 голосов
/ 15 октября 2018

Вы не должны исправлять функцию, которая находится в вашем локальном модульном (то есть «глобальном» - в Python пространстве имен - «фактически» модуле).

Когда в Python вы делаете

from module.that import this

this становится переменной в модуле, который содержит оператор импорта.Любые изменения в файле «module.that.this» будут влиять на объект, указанный в другом модуле, но использование только this все равно будет ссылаться на исходный объект.

Возможно, ваш код не совсем такой, как вы нам показываетеили, может быть, "mock.pacth" может обнаружить, что локальный модуль call_command указывает на django.core.management.call_command в другом модуле, когда он делает исправление - но не при обращении исправления.Дело в том, что ваше локальное имя модуля call_command изменяется.

Это можно исправить, просто изменив код, чтобы не привязывать переменную модуля непосредственно к функции, которую вы хотите изменить:

из django.core import management def test_run_migrations_raise_exception (self):

with mock.patch('django.core.management.call_command', return_value=None, side_effect=Exception('e message')):
    self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)
    management.call_command('run_data_migrations')
    self.check_migrations_called(MigrationTracker.objects.all(), data_migrations_settings_in_db)

Надеюсь, вы поймете это и решите эту проблему.Тем не менее, это использование mock не имеет никакого смысла вообще: идея использования mock заключается в том, что некоторые вызываемые элементы, косвенно используемые кодом, который вы вызываете в кодовом блоке, который применяет патч, не имеют первоначального эффекта - поэтомуПроникнуть код может быть запущен и протестирован.Вы вызываете непосредственно фиктивный объект - так что он не будет иметь никакого исходного кода - вызов call_command('run_data_migrations') вообще не запускает код на вашей кодовой базе, и, следовательно, там нечего тестировать.Он просто вызывает поддельный экземпляр и не изменит статус чего-либо, что может быть обнаружено с помощью check_migrations_called.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...