[TIP] Mocking properties on an instance
fuzzyman at voidspace.org.uk
Sun Sep 4 08:56:11 PDT 2011
On 4 Sep 2011, at 02:20, Julian Berman wrote:
> So, I'm aware of mock.patch.object, but I have a use case at hand that seems to most easily be accomplished by patching properties (/ arbitrary descriptors) on an already existing instance.
> Here's a test case showing my use case, along with a partial implementation that happens to work for me.
> It happens to be that in my case, as of right now I have strictly non-data descriptors, so the quickly thrown together implementation simply uses the AttributeError (yeah sorry :P) to tell if we have a property or not, but obviously this could be done by checking to see if the class' attr has __get__ defined.
Interesting. I've long known that the one thing you can't do with patch is patch out a property, or other property-like descriptor, on an *instance*. This isn't normally a problem because you can patch on the class instead - but of course that doesn't work where you have multiple instances to patch.
I haven't dealt with this previously as you're the first person to report it as a problem in practise rather than just in theory. :-)
Your solution is fine, so long as there is no property setter (the AttributeError must be raised when attempting to put the patch in place in order to detect the problem). So I don't think this is a *general* solution.
A general solution would involve replacing the descriptor on the class with something that knows what instances have been patched and delegates to the real descriptor for any other instance.
I've created an issue to track the problem. It's too late to get a fix into 0.8, but I'll consider the issue for the next release:
All the best,
> As far as some quick thought can tell, the only issue with this would be when klass.foo was a thing with __get__ while instance_of_klass.foo was an evil thing that replaced the descriptor on itself, but I highly doubt that's something at all to worry about?
> Is there a particular aversion to including at least the possibility of trying to patch a property on an instance by doing something similar?
> testing-in-python mailing list
> testing-in-python at lists.idyll.org
May you do good and not evil
May you find forgiveness for yourself and forgive others
May you share freely, never taking more than you give.
-- the sqlite blessing
More information about the testing-in-python