charlax charlax - 17 days ago 6
Python Question

How to mock a readonly property with mock?

How do you mock a readonly property with mock?

I tried:

setattr(obj.__class__, 'property_to_be_mocked', mock.Mock())


but the issue is that it then applies to all instances of the class... which breaks my tests.

Do you have any other idea? I don't want to mock the full object, only this specific property.

Thanks!

Answer

Actually, the answer was (as usual) in the documentation, it's just that I was applying the patch to the instance instead of the class when I followed their example.

Here is how to do it:

class MyClass:
    @property
    def last_transaction(self):
        # an expensive and complicated DB query here
        pass

In the test suite:

def test():
    # Make sure you patch on MyClass, not on a MyClass instance, otherwise
    # you'll get an AttributeError, because mock is using settattr and
    # last_transaction is a readonly property so there's no setter.
    with mock.patch(MyClass, 'last_transaction') as mock_last_transaction:
        mock_last_transaction.__get__ = mock.Mock(return_value=Transaction())
        myclass = MyClass()
        print myclass.last_transaction
Comments