Как мне исправить метод python для запуска тестового примера? - PullRequest
0 голосов
/ 08 июня 2018

Проект, над которым я работаю, использует django практически для всего.При написании модели я счел необходимым переопределить метод save (), чтобы выделить задачу, выполняемую работником:

class MyModel(models.Model)
    def _start_processing(self):
        my_task.apply_async(args=['arg1', ..., 'argn'])
    def save(self, *args, **kwargs):
        """Saves the model object to the database"""
        # do some stuff
        self._start_processing()
        # do some more stuff
        super(MyModel, self).save(*args, **kwargs)

В моем тестере я хочу протестировать части сохраненияпереопределить, которые обозначены # do some stuff и # do some more stuff, но не хотят запускать задачу.Чтобы сделать это, я считаю, что я должен использовать насмешки (которые я очень новичок).

В моем тестовом классе я настроил его на пропуск вызова задачи:

class MyModelTests(TestCase):
    def setUp(self):
        # Mock the _start_processing() method. Ha!
        @patch('my_app.models.MyModel._start_processing')
        def start_processing(self, mock_start_processing):
            print('This is when the task would normally be run, but this is a test!')

        # Create a model to test with
        self.test_object = MyModelFactory()

Поскольку фабрика создает и сохраняет экземпляр модели, мне нужно перезаписать_start_processing() метод до этого вызывается.Вышеприведенное, похоже, не работает (а задача запускается и не выполняется).Чего мне не хватает?

1 Ответ

0 голосов
/ 08 июня 2018

Прежде всего, вы должны заключить в декоратор не функцию, которую вы хотите использовать в качестве замены, а «область», в которой должен работать ваш макет.Так, например, если вам нужно смоделировать _start_processing для всего класса MyModelTests, вы должны поместить декоратор перед определением класса.Если только для одного метода тестирования - оберните им только метод теста.

Во-вторых, определите, что start_processing функция где-то вне класса, и передайте @patch('my_app.models.MyModel._start_processing', new=start_processing), чтобы он знал, что использовать в качестве замены дляактуальный метод.Но имейте в виду, что она соответствует фактической сигнатуре метода, поэтому используйте просто

def start_processing(self):
    print('This is when the task would normally be run, but this is a test!')

В-третьих, вам нужно будет добавить аргумент mock_start_processing к каждому тестовому случаю внутри этого класса (методы test _...), просто потому, чтоиздевательство работает так:).

И наконец.Вы должны знать о target, который вы исправляете.Ваш текущий my_app.models.MyModel._start_processing может быть сломан.Вы должны пропатчить класс, используя путь, в котором он используется, а не там, где он определен.Итак, если вы создаете объекты с MyModelFactory внутри TestCase, а MyModelFactory живет с my_app.factories и импортирует MyModel как from .models import MyModel, вам придется использовать @patch('my_app.factories.MyModel._start_processing'), а не 'my_app.models.MyModel._start_processing'.

Надеюсь, это поможет.

...