在__init __

时间:2015-12-29 23:41:07

标签: python unit-testing python-mock

我正在尝试为应用程序编写一些单元测试,并使用python mock。我熟悉其他嘲弄图书馆,直到现在还有很多麻烦。我试图在父类的 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对调用本身而不是属性对象作出反应吗?

1 个答案:

答案 0 :(得分:1)

attributeBeginningChain实例属性由__init__设置,因此patch调用中ApplicationUnderTest来电设置的修补静态值将被__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来电。