代码之家  ›  专栏  ›  技术社区  ›  Livioso

带有@patch decorator的模拟类属性

  •  0
  • Livioso  · 技术社区  · 8 年前

    如何使用 @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: <class '(...).TelefonyInterface'> does not have the attribute 'call'
    

    我的电话接口是这样的:

    class TelefonyInterface:
        def __init__(self):
            self.call = None
    
        def dial(self, number):
            self.call = ...
    
        def hangup(self):
            if self.call:
                self.call.hangup()
    
        ...
    

    正确的方法是什么?

    1 回复  |  直到 8 年前
        1
  •  3
  •   Matthew Story    8 年前

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