mardi 29 décembre 2015

Python mock attributes defined and set within __init__

I am trying to write some unit tests for an application and I using python mock. I am familiar with other mocking libraries and haven't had much trouble until now. I am trying to mock a chained call on an attribute set within the init block of the parent class. Here is an example of what I need:

class ApplicationUnderTest:

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

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

I need the chained call to throw an error. I have tried resolving this in the following manner:

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

The last assertion fails so I am pretty sure this isn't the way to do this. I have also tried:

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

That throws the error:

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

I cannot make alterations to the code under test, so my question is how can I mock chained calls made on attributes set under the _init__ function? I have read that this is not possible but surely there must be a work around? Can I perhaps somehow instruct the mock fixture to react to the call itself rather than the attribute object via autospec?

Aucun commentaire:

Enregistrer un commentaire