I have a software package, packageA
, which has an optional dependency on packageB
. If packageB
is installed, then the user has access to some additional functionality. But, not having it installed does not limit the use of packageA
.
I want to write a unit (or integration?) test that checks packageA
is still usable if packageB
is not installed... that is, it won't unexpectedly throw an ImportError
for packagB
The test I have is written like this:
from unittest import mock
import pytest
def test_no_err_if_packageb_not_installed():
import sys
sys.modules['packageB'] = mock.MagicMock()
try:
from packageA import file_that_uses_packageb # noqa: F401
except NameError:
pytest.fail("packagB dependency found at root level")
And this works, if it's called in isolation. But when it's called as part of the testing suite, this test will always pass. This is because sys.modules
will already have been populated with the import modules by previous tests. I've tried to del
the package from sys.modules
first, but this doesn't work
What is the correct way to write this test?
Edit with working solution
from unittest import mock
import pytest
def test_no_err_if_packageb_not_installed():
import sys
# clear cached modules
mods = list(sys.modules.keys())
for mod in mods:
if 'packageA' in mod or 'packageB' in mod:
del sys.modules[mod]
sys.modules['packageB'] = mock.MagicMock()
try:
from packageA import file_that_uses_packageb # noqa: F401
except NameError:
pytest.fail("packagB dependency found at root level")
del sys.modules['packageB']