【问题标题】:Python mock attributes defined and set within __init__在 __init__ 中定义和设置的 Python 模拟属性
【发布时间】:2015-12-29 23:41:06
【问题描述】:

我正在尝试为应用程序编写一些单元测试,并且我使用 python 模拟。我熟悉其他模拟库,直到现在还没有遇到太多麻烦。我正在尝试模拟对父类的 init 块中的属性集的链式调用。这是我需要的示例:

class ApplicationUnderTest:

    def __init__(self):
      self.attributeBeginningChain = SomeClass(False)

    def methodWithChain(self):
      object = self.attributeBeginningChain.methodOfSomeClass()

我需要链式调用来引发错误。我尝试通过以下方式解决此问题:

@patch.object(SomeClass(False), 'methodOfSomeClass', side_effect=ErrorClass)
def test_chained_call(self, mock_someclass):
    A = ApplicationUnderTest.methodWithChain()
    self.assertTrue(mock_someclass.called)

最后一个断言失败了,所以我很确定这不是这样做的方法。我也试过:

@patch('ApplicationUnderTest.attributeBeginningChain')
def test_chained_call(self, mock_someclass):
    mock_someclass.methodOfSomeClass.side_effect = ErrorClass
    A = ApplicationUnderTest.methodWithChain()
    self.assertTrue(mock_someclass.called)

这会引发错误:

AttributeError: package.ApplicationUnderTest does not have the attribute 'attributeBeginningChain'

我无法更改被测代码,所以我的问题是如何模拟对在 _init__ 函数?我读过这是不可能的,但肯定有解决办法吗?我是否可以通过 autospec 以某种方式指示模拟夹具对调用本身而不是属性对象做出反应?

【问题讨论】:

    标签: python unit-testing python-mock


    【解决方案1】:

    attributeBeginningChain 实例属性由__init__ 设置,因此您在ApplicationUnderTest 调用中通过patch 调用设置的修补静态值将被__init__ 调用覆盖。

    您应该修补 ApplicationUnderTest 实例:

    def test_chained_call(self):
        A = ApplicationUnderTest()
        with patch.object(A, 'attributeBeginningChain') as mock_someclass:
            mock_someclass.methodOfSomeClass.side_effect = ErrorClass
            with self.assertRaise(ErrorClass):
                A.methodWithChain()
    

    另一种可能是直接打补丁SomeClass.methodOfSomeClass

    @patch('package.SomeClass.methodOfSomeClass', side_effect=ErrorClass)
    def test_chained_call(self, mock_methodOfSomeClass):
        with self.assertRaise(ErrorClass):
            ApplicationUnderTest().methodWithChain()
    

    我不确定您的对象在哪里以及应该如何修补它们:查看where to patch 以了解您应该如何使用patch 调用。

    【讨论】:

    • 感谢您的回复!我还没有尝试过(继续做其他事情),但我会检查一下并在我回到它时做出回应。
    猜你喜欢
    • 2018-02-23
    • 2011-04-25
    • 2019-03-02
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    • 2015-11-29
    • 2011-06-16
    • 2015-03-07
    相关资源
    最近更新 更多