Mocks - Where to Patch?
Where to Patch?#
A fundmental lesson to learn when it comes to mocks is…
For about 5 years, this mind was patching in the wrong place…
patch()
works by (temporarily) changing the object that a name points to with another one
There can be many names pointing to any individual object, so for patching to work you must ensure that you patch the name used by the system under test.
The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.
Let that be started again…
Patch where an object is looked up (where it is imported)
a.py
-> Defines SomeClass
b.py
-> from a import SomeClass
-> some_function instantiates SomeClass
- If we use
patch()
to mock outa.SomeClass
then it will have no effect on our test - module
b
already has a reference to the realSomeClass
The key is to patch out SomeClass where it is used (or where it is looked up):
@patch('b.SomeClass')
However if in b.py
it does:
import a
my_obj = a.SomeClass()
in this case, the functional patch would be:
@patch('a.SomeClass')