New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spying on properties #35

blueyed opened this Issue Feb 29, 2016 · 5 comments


None yet
4 participants

blueyed commented Feb 29, 2016

I've tried to use spy on object properties, but it fails with AttributeError: can't set attribute in unittest/

I've started looking into adding support for (through PropertyMock), but failed to make it work without accessing/calling the property method during setup of the spy - it would be better to only call it when it's accessed from the test.

I would appreciate any feedback / help in this regard.


This comment has been minimized.


nicoddemus commented Feb 29, 2016

I'm not sure @blueyed... I think it would certainly be an useful feature. Do you have some sample code to share?

cc @fogo


This comment has been minimized.


blueyed commented Mar 1, 2016

My idea was to first patch the class to allow setting a new attribute (using PropertyMock) and then patch the attribute itself.
But it felt like having to patch/use fget/fset from the property class itself.


This comment has been minimized.


fogo commented Mar 2, 2016

This a nice feature that I didn't even think about because I guess never really mocked a property before.

Below it is a draft I've come up in a hurry that is really buggy but get the basics done:

def spy(self, obj, name):
        if isinstance(getattr(obj, name), property):
            prop = getattr(obj, name)

            class SpyPropertyMock(mock_module.PropertyMock):

                def __get__(self, obj, obj_type):
                    return prop.__get__(obj)

                def __set__(self, obj, val):
                    prop.fset(obj, val)

            result = self.patch.object(obj, name, new_callable=SpyPropertyMock)
            return result
            method = getattr(obj, name)

            autospec = inspect.ismethod(method) or inspect.isfunction(method)
            # Can't use autospec classmethod or staticmethod objects
            # see:
            if inspect.isclass(obj):
                # bypass class descriptor:
                value = obj.__getattribute__(obj, name)
                if isinstance(value, (classmethod, staticmethod)):
                    autospec = False

            result = self.patch.object(obj, name, side_effect=method,
            return result

A test using it:

def testFoo(mocker):
    mocked = mocker.spy(Foo, 'foo')

    foo = Foo() = 'b'

    assert == 'b'
    assert != 'c'
    assert != 'd'
    print mocked.mock_calls  #  [call(u'b'), call(), call(), call()]

With this, the mock object returned can be used to inspect mock_calls to property and property value is in fact changed.

Problems I've seen so far:

  • I'm unable to access without getting errors.
  • Different from method spies, object accessed by foo attr isn't a mock object, so it is only possible to access mock call objects through returned object.

Anyway I have to get more used to PropertyMock before moving on, let me know more details about your problems and implementation (maybe open a PR?) because I can try to help :)


This comment has been minimized.

fliiiix commented Mar 23, 2018

Is there any progress?


This comment has been minimized.


nicoddemus commented Mar 23, 2018

I don't think so, but I would be happy to review and merge a PR! 😁

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment