Search code examples
python-unittestpython-unittest.mock

Python unittest Mock an object to not have an attribute


I have a function that runs some code if the object has a certain attribute, and in rare cases if if the object does not have the attribute, it runs different code. It is hard for me to create the object without the attribute for testing. I tried del instance.attribute but got an error. The attribute is actually a @property under the hood.

I have an object instance that has foo attribute. How does one mock it so that when one tries to access instance.foo it raises an AttributeError as usual if there is no attribute?

I tried mock.Mock(side_effect=AttributeError('Boom!')) but it only works with methods.


Solution

  • You could try to use a PropertyMock for the property, and generally you shall be able to set the respective side effect. Here is a simple working example:

    from unittest import mock
    import pytest
    
    class Foo:
        @property
        def bar(self):
            return "bar"
    
    
    def test_no_foo():
        bar_mock = mock.PropertyMock()
        with mock.patch(f"{__name__}.Foo.bar", bar_mock):
            bar_mock.side_effect = AttributeError('Boom!')
            foo = Foo()
            with pytest.raises(AttributeError):
                foo.bar
    

    As you patch the property in the class, not in the object, you can can also do this using patch.object if you have access to the object by accessing the class of the object:

    def test_no_foo():
        bar_mock = mock.PropertyMock()
        foo = Foo()
        with mock.patch.object(foo.__class__, "bar", bar_mock):
            bar_mock.side_effect = AttributeError('Boom!')
            with pytest.raises(AttributeError):
                foo.bar