Модуль Mocking и все подмодули перед импортом - PullRequest
0 голосов
/ 27 марта 2019

Я имею дело с базой кодов, которая имеет большое количество модулей, которые создают экземпляры соединений с базой данных, считывают данные из реестра и т. Д. При импорте. (Код в основной функции или в классе, но в глобальной области видимости). Я буду называть эти модули «плохие модули».

По причинам, выходящим за рамки этого вопроса, мне нужно иметь возможность импортировать другие библиотеки («хорошие модули»), полагаясь на эти библиотеки без сбоев, и моя среда такова, что эти библиотеки не будут работать при импорте.

В данный момент я делаю это, где 'idmlib' является плохим модулем, а все его дочерние элементы являются плохими модулями:

sys.modules['idmlib'] = MagicMock()
sys.modules['idmlib.idmobject'] = Mock()
sys.modules['idmlib.idapi'] = Mock()
sys.modules['idmlib.database'] = Mock()
sys.modules['idmlib.plugins'] = Mock()
sys.modules['idmlib.plugins.authmod'] = Mock()

... other code ...

Это прекрасно работает, но мне нужно предсказать каждого ребенка, внука и т. Д. idmlib, которые будут импортированы.

Вместо этого я хотел бы сделать общий вывод idmlib и всех его подмодулей заранее, без необходимости знать, что представляют собой все эти подмодули.

Есть ли способ превратить sys.modules['idmlib'] в MagicMock, чьи подмодули также являются MagicMock s?

Моя первая мысль состоит в том, чтобы sys.modules был макетом, обертывающим оригинал sys.modules, который имеет некоторое альтернативное поведение, если его проверяют на что-то, начинающееся с 'idmlib' и в противном случае просто взаимодействующее с оригинальным словарем.

К сожалению, это вызывает бесконечную рекурсию.

original_sys_modules = sys.modules
mock_sys_modules = MagicMock(wraps=original_sys_modules)


sys.modules = mock_sys_modules
import psutil

Ошибка:

Traceback (most recent call last):
  File "dryrun-script.py", line 26, in <module>
    import psutil
  File "C:\Users\danie01.AD\.virtualenvs\robotframework-O8sDx-L-\lib\site-packages\psutil\__init__.py", line 41, in <module>
    from . import _common
  File "C:\Users\danie01.AD\.virtualenvs\robotframework-O8sDx-L-\lib\site-packages\psutil\__init__.py", line 41, in <module>
    from . import _common
  File "C:\Users\danie01.AD\.virtualenvs\robotframework-O8sDx-L-\lib\site-packages\psutil\__init__.py", line 41, in <module>
    from . import _common
  File "C:\Users\danie01.AD\.virtualenvs\robotframework-O8sDx-L-\lib\site-packages\psutil\__init__.py", line 41, in <module>
    from . import _common
  File "C:\Users\danie01.AD\.virtualenvs\robotframework-O8sDx-L-\lib\site-packages\psutil\__init__.py", line 41, in <module>
    from . import _common
  File "C:\Users\danie01.AD\.virtualenvs\robotframework-O8sDx-L-\lib\site-packages\psutil\__init__.py", line 41, in <module>
    from . import _common
  File "C:\Users\danie01.AD\.virtualenvs\robotframework-O8sDx-L-\lib\site-packages\psutil\__init__.py", line 41, in <module>
    from . import _common
  File "C:\Users\danie01.AD\.virtualenvs\robotframework-O8sDx-L-\lib\site-packages\psutil\__init__.py", line 41, in <module>
    from . import _common
    ...
...