Python: макет модуля, который вызывает исключение - PullRequest
0 голосов
/ 30 сентября 2019

Мне нужно протестировать функцию в модуле, который импортирует другой модуль, который вызывает исключение при импорте.

#a.py
raise ValueError("hello")
my_const = 'SOMETHING'


#b.py
from a import my_const 

def foo():
    # do something with my_const 
    return "expected_result"  

#test_foo.py
def test_foo():
    from b import foo
    assert foo() == "expected_result"

Здесь, когда я импортирую foo в test_foo.py, a.py импортируется в b.py, возникает исключение, и импорт никогда не завершается, поэтому my_const недоступен в b.py.

Мне не разрешено изменять ни a.py, ни b.py. Кроме того, использование unittest.patch и @patch('a', 'my_const') приводит к импорту a.py, поэтому он не работает.

Возможно создать модуль динамически с помощью lib импорта и добавить его в sys.modules, но он естьдругое решение, которое не требует importlib?

1 Ответ

1 голос
/ 30 сентября 2019

Насколько я знаю, вы можете динамически создавать и импортировать модуль. Вот код, вдохновленный разделом «Приближенное importlib.import_module ()» в документации import lib

from importlib.util import module_from_spec, find_spec
import sys

def patched_import(name, **kwargs):
    spec = find_spec(name)
    m = module_from_spec(spec)

    for k in kwargs:
        setattr(m, k, kwargs[k])
    sys.modules[name] = m 

Правка: мое решение должно быть в порядке для макета, ноосторожно, поскольку манипуляции со ссылками могут иметь побочные эффекты.

Чтобы использовать его, просто выполните:

patched_import('a', my_const='stuff')

Перед импортом b.py.

...