Використання макетної виправлення для знущання над методом екземпляра


83

Я намагаюся щось знущатись під час тестування програми Django, використовуючи образотворчу бібліотеку Mock testing . Здається, я не можу змусити це працювати, я намагаюся зробити це:

models.py

from somelib import FooClass

class Promotion(models.Model):
    foo = models.ForeignKey(FooClass)
    def bar(self):
       print "Do something I don't want!"


test.py

class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'

    def test_enter_promotion(self):
        @patch.object(my_app.models.FooClass, 'bar')
        def fake_bar(self, mock_my_method):
            print "Do something I want!"
            return True

        self.client.get(reverse(view))

Що я роблю не так?


barнасправді є "методом екземпляра", і єдиним його параметром є self. Щоб бути методом класу, його потрібно було б параметризувати за допомогою clsта викликати як Promotion.foo().
cavaunpeu

Об’єкт, що підлягає виправленню, потрібно цитувати так: @patch.object('my_app.models.FooClass', 'bar')
Ласма

2
@cavaunpeu - не (просто) параметризований за допомогою cls, але що більш важливо (оскільки selfі clsне означає нічого особливого в python), прикрашений@classmethod
dwanderson

Відповіді:


69

Щоб додати до відповіді Кіта, вказавши 3-й аргумент, що patch.object()дозволяє вказати знущаний об’єкт / метод. В іншому випадку використовується MagicMockоб’єкт за замовчуванням .

    def fake_bar(self):
        print "Do something I want!"
        return True

    @patch.object(my_app.models.FooClass, 'bar', fake_bar)
    def test_enter_promotion(self):
        self.client.get(reverse(view))
        # Do something I want!

Зверніть увагу , що, якщо ви вкажете знущальний об'єкт, то за замовчуванням MagicMock()буде більше не передається в виправленої об'єкт - наприклад , більше не:

def test_enter_promotion(self, mock_method):

але замість цього:

def test_enter_promotion(self):

http://www.voidspace.org.uk/python/mock/patch.html#patch-object


Я віддаю перевагу цій реалізації. Це зрозуміліше, особливо для початківців у модульному тестуванні.
Дорсіоман 07.03.20

36

Ах, я був збентежений, де застосувати декоратор патчів. Виправлено:

class ViewsDoSomething(TestCase):
    view = 'my_app.views.do_something'

    @patch.object(my_app.models.FooClass, 'bar')
    def test_enter_promotion(self, mock_method):
        self.client.get(reverse(view))

21
Де ви зараз встановлюєте зв'язок між методом, що знущається, і фальшивою реалізацією?
physicalattraction

@physicalattraction, з'єднання здійснюється аргументом, mock_methodпереданим тестовій функції. Я зміг використовувати цю техніку в одному зі своїх тестів. Це корисно, коли потрібно лише перевірити, чи був викликаний знущальний метод.
Калян Ведала

@ rcode74: Як виправити метод екземпляра (якогось іншого об'єкта) всередині методу тестування. наприклад: def my_method_to_be_tested (...): r = some_script.some_class (...); r.how_to_patch_this_method.
imsrgadich

1
@imsrgadich, ти зробив би щось на зразок r.how_to_patch_this_method = MagicMock (). Ви можете перевірити документацію MagicMock, щоб побачити, як призначити поведінку макетному об’єкту.
Калян Ведала
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.