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 theCONST
attribute of the module objectmod1.mod2
to a different object. It does not affect any existing names referencing the originalmod1.mod2.CONST
object.When
utils.py
does:it creates a name
CONST
in the namespace of themod1.mod2.utils
module, referencing the object-1
currently referenced by themod1.mod2.CONST
name.And when
test_mod_function
then does:it modifies
mod1.mod2
such that itsCONST
attribute now references aMock
object, while theCONST
name inmod1.mod2.utils
continues to reference the object-1
, which is why settingmock.return_value
does not affect the outcome ofmod_function
.To properly test
mod_function
with a mockCONST
you can either patchCONST
in the namespace wheremod_function
is defined:or you can defer the import of
mod1.mod2.utils
untilmod1.mod2.CONST
has been patched: