monkeypatch builtins importlib
Source
- use the (already defined) pytest
monkeypatchfixture to temporarily modify the state of thebuiltinsmodule and thesys.modulesdict - define a custom import function that raises
ImportErrorwhen a certain module (in this case namedlabbcan) is requested to be imported - force a reload of the module that imports the module that should be mocked to be not existent (in this case
cetoni_qtro_models.linear_scaling)
→ this reload will in turn try to importlabbcanagain which will fail with anImportError
import builtins
import importlib
import sys
from collections.abc import Mapping, Sequence
from types import ModuleType
import pytest
realimport = builtins.__import__
def no_labbcan_import(
name: str,
globals: Mapping[str, object] | None = None, # noqa: A002
locals: Mapping[str, object] | None = None, # noqa: A002
fromlist: Sequence[str] = (),
level: int = 0,
) -> ModuleType:
if name.startswith("labbcan"):
raise ImportError
return realimport(name, globals, locals, fromlist, level)
def test_import_error(monkeypatch: pytest.MonkeyPatch) -> None:
with monkeypatch.context() as m:
m.setattr(builtins, "__import__", no_labbcan_import)
m.delitem(sys.modules, "cetoni_qtro.models.linear_scaling")
importlib.reload(cetoni_qtro.models)
from cetoni_qtro.models.linear_scaling import LinearScaling
# test what ever you like without labbcan being imported if the reloaded module already
# handles the `ImportError` gracefully
# or
with pytest.raises(ImportError):
importlib.reload(cetoni_qtro.models)
from cetoni_qtro.models.linear_scaling import LinearScaling