I have a structure like so:
mod1
├── mod2
│ ├── __init__.py
│ └── utils.py
└── tests
└── test_utils.py
where
__init__.py:
CONST = -1
utils.py:
from mod1.mod2 import CONST
def mod_function():
print(CONST)
test_utils.py:
from mod1.mod2.utils import mod_function
def test_mod_function(mocker):
mock = mocker.patch("mod1.mod2.CONST")
mock.return_value = 1000
mod_function()
By running python -m pytest -s ./mod1/tests I expected to see 1000 as an output, but got -1. Why?
How to patch a constant from the __init__.py file?
What
patch("mod1.mod2.CONST")does is really to set theCONSTattribute of the module objectmod1.mod2to a different object. It does not affect any existing names referencing the originalmod1.mod2.CONSTobject.When
utils.pydoes:it creates a name
CONSTin the namespace of themod1.mod2.utilsmodule, referencing the object-1currently referenced by themod1.mod2.CONSTname.And when
test_mod_functionthen does:it modifies
mod1.mod2such that itsCONSTattribute now references aMockobject, while theCONSTname inmod1.mod2.utilscontinues to reference the object-1, which is why settingmock.return_valuedoes not affect the outcome ofmod_function.To properly test
mod_functionwith a mockCONSTyou can either patchCONSTin the namespace wheremod_functionis defined:or you can defer the import of
mod1.mod2.utilsuntilmod1.mod2.CONSThas been patched: