When a method of an object is called, it's first parameter is a reference to the object that contains the method. We'd like to be able to replace it with a mock, because that's the only way to truly separate each method, so that each can be tested as an individual unit. If we can't mock self
, the methods will tend to interfere with each other's tests by interacting via their containing object.
The stumbling block in all this is that the self
object isn't passed explicitly by the caller when a method gets called: Python already knows which object the method is bound to, and fills it in automatically. How can we substitute a mock for a parameter that doesn't come from us?
We can solve this problem by finding the function that we're testing in its class and invoking it directly, rather than invoking it as a method bound to an object. That way, we can pass all of the parameters, including the first one, without the interpreter performing any of its magic.