【问题标题】:Mock class attribute with @patch decorator使用 @patch 装饰器模拟类属性
【发布时间】:2018-12-04 12:23:46
【问题描述】:

如何使用@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()

    ...

这样做的正确方法是什么?

【问题讨论】:

    标签: python mocking patch python-decorators


    【解决方案1】:

    这里的问题是你正在修补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)
    

    【讨论】:

    • 谢谢!嗯,这是有道理的。 :)
    猜你喜欢
    • 2018-10-08
    • 1970-01-01
    • 2017-11-19
    • 1970-01-01
    • 2013-08-19
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多