使用@patch装饰器模拟类属性

时间:2018-06-25 21:02:09

标签: python mocking patch python-decorators

如何使用@patch装饰器模拟正在测试的类的对象属性?

给出以下测试:

def test_hangup(self):
    stub_call = Mock()

    cut = TelefonyInterface()
    cut.call = stub_call
    cut.hangup()

    self.assertEqual(1, stub_call.hangup.call_count)
    self.assertEqual(None, cut.call)

我想在这里使用mock.patch装饰器使其更易于阅读。像这样:

@patch.object(TelefonyInterface, 'call')
def test_hangup(self, call):
    cut = TelefonyInterface()
    cut.hangup()

    self.assertEqual(1, call.hangup.call_count)
    self.assertEqual(None, cut.call)

但是我得到以下AttributeError:

AttributeError: <class '(...).TelefonyInterface'> does not have the attribute 'call'

我的TelefonyInterface看起来像这样:

class TelefonyInterface:
    def __init__(self):
        self.call = None

    def dial(self, number):
        self.call = ...

    def hangup(self):
        if self.call:
            self.call.hangup()

    ...

执行此操作的正确方法是什么?

1 个答案:

答案 0 :(得分:2)

这里的问题是您正在修补TelefonyInterface类,该类没有属性call。该属性是在初始化时在实例上定义的。要完成您想要修补实例而不是类的操作:

def test_hangup(self):
    cut = TelefonyInterface()
    with patch.object(cut, 'call') as call:
        cut.hangup()

        self.assertEqual(1, call.hangup.call_count)
        self.assertEqual(None, cut.call)
相关问题