Использование макетного патча для издевательства метода экземпляра

Я пытаюсь что-то издеваться над тестированием приложения Django с помощью воображаемой Mock test library. Кажется, я не могу заставить его работать, я пытаюсь сделать это:

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

Что я делаю неправильно?

Ответ 1

А я был смущен тем, где применять этот патч-декоратор. Исправлено:

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

Ответ 2

Чтобы добавить в ответ Kit, указание 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