The other day I spent far too much time trying to figure out how to mock a module-level function that was being used inside of my class's method in Python. My googling didn't lead to obvious answers, so I figured it'd be good to document here for future reference.
Imagine we have some module-level function like the following:
# file: project/some_module/functions.py
def fetch_thing():
# query some database
return data
And that we use it inside of a class within a different module:
# file: project/other_module/thing.py
from some_module.functions import fetch_thing
class Thing:
def run(self):
try:
data = fetch_thing()
except:
self.fail_gracefully()
In this example, I want to test that a failure fetching from the db will fail gracefully, so I need to mock fetch_thing
and have it raise an exception.
I kept trying to mock the function at its module path, like so:
from other_module.thing import Thing
thing = Thing()
with patch.object('some_module.functions.fetch_thing') as mocked:
mocked.side_effect = Exception('mocked error')
data = thing.run()
But this isn't right. It turns out that you need to mock/patch the function within the module it's being imported into.
from other_module.thing import Thing
thing = Thing()
with patch.object('other_module.fetch_thing') as mocked:
mocked.side_effect = Exception('mocked error')
data = thing.run()
Note the very subtle difference in the string path we are passing to patch.object
. Because we are importing the function into other_module
where our class uses it, that is what we need to mock.