Модуль A
включает import B
в себя в верхней части. Однако в условиях испытания , я хотел бы, чтобы дразнить B
в A
(макет A.B
) и полностью отказаться от импорта B
.
На самом деле, B
не установлен в тестовой среде специально.
A
это тестируемое устройство. Я должен импортировать A
со всеми его функциями. B
это модуль, который мне нужно издеваться Но как я могу издеваться B
внутри A
и перестать A
импортировать реальное B
, если первым делом A
это импорт B
?
(Причина, по которой B не установлен, заключается в том, что я использую pypy для быстрого тестирования, и, к сожалению, B еще не совместим с pypy.)
Как это можно сделать?
источник
Mock
не будет исправлять некоторые магические атрибуты (__%s__
), как__name__
.sys.modules['B'] = None
но это не сработало.mock
а затем позвонитьmock.Mock()
Встроенный модуль
__import__
может быть смоделирован с помощью библиотеки 'mock' для большего контроля:Скажи
A
выглядит так:A.a()
возвращает,b_mock.func()
которые также могут быть высмеяны.Примечание для Python 3: Как указано в журнале изменений для 3.0 ,
__builtin__
теперь он называетсяbuiltins
:Код в этом ответе работает нормально , если заменить
__builtin__
наbuiltins
на Python 3.источник
import_mock
зовутimport A
, но не за что-то импортируемое.ImportError: No module named '__builtin__'
__builtin__
__builtin__
наbuiltins
для Python3 ( docs.python.org/3/whatsnew/3.0.html?highlight=__builtin__ )Легко, просто смоделируйте библиотеку в sys.modules, прежде чем она будет импортирована:
и затем, если только
A
не полагаться на конкретные типы данных, возвращаемых из объектов B:должен просто работать.
Вы также можете издеваться
import A.B
:Это работает, даже если у вас есть подмодули, но вы захотите смоделировать каждый модуль. Скажем, у вас есть это:
Чтобы смоделировать, просто сделайте ниже, прежде чем импортировать модуль, который содержит выше:
(Мой опыт: у меня была зависимость, которая работает на одной платформе, Windows, но не работала на Linux, где мы проводим наши ежедневные тесты. Поэтому мне нужно было смоделировать зависимость для наших тестов. К счастью, это был черный ящик, поэтому Мне не нужно было устанавливать много взаимодействия.)
Дразнящие побочные эффекты
Приложение: На самом деле мне нужно было смоделировать побочный эффект, который занял некоторое время. Поэтому мне нужен был метод объекта, чтобы поспать секунду. Это будет работать так:
И затем выполнение кода занимает некоторое время, как настоящий метод.
источник
Я понимаю, что немного опоздал на вечеринку здесь, но вот несколько безумный способ автоматизировать это с
mock
библиотекой:(вот пример использования)
Причина, по которой это так нелепо сложно, заключается в том, что когда импорт происходит, Python в основном делает это (например,
from herp.derp import foo
)sys.modules['herp']
? Остальное импортируй. Если все еще нетImportError
sys.modules['herp.derp']
? Остальное импортируй. Если все еще нетImportError
foo
изsys.modules['herp.derp']
. ещеImportError
foo = sys.modules['herp.derp'].foo
У этого взломанного совместного решения есть некоторые недостатки: если что-то еще зависит от других элементов в пути модуля, этот тип переворачивает его. Кроме того, это работает только для вещей, которые импортируются встроенными, таких как
или
источник
Ответ Аарона Холла работает на меня. Просто хочу упомянуть одну важную вещь,
если в
A.py
тебеfrom B.C.D import E
тогда в
test.py
вас надо издеваться над каждым модулем по пути, иначе вы получитеImportError
источник
Я нашел хороший способ издеваться над импортом в Python. Это Zaadi Эрика решение найдено здесь , которые я просто использую в моем Django приложения.
У меня есть класс,
SeatInterface
который является интерфейсом кSeat
модельному классу. Так что внутри моегоseat_interface
модуля у меня есть такой импорт:Я хотел создать изолированные тесты для
SeatInterface
класса с поддельнымSeat
классом какFakeSeat
. Проблема была в том, как запускать тесты в автономном режиме, когда приложение Django не работает. У меня была ниже ошибка:Решение было:
И тогда тест волшебным образом проходит нормально :)
источник
Если вы делаете,
import ModuleB
вы действительно вызываете встроенный метод__import__
как:Вы можете перезаписать этот метод, импортировав
__builtin__
модуль и сделав обертку вокруг__builtin__.__import__
метода. Или вы можете играть сNullImporter
крючком изimp
модуля. Перехват исключения и макет вашего модуля / класса вexcept
-блоке.Указатель на соответствующие документы:
docs.python.org:
__import__
Доступ к внутренним объектам импорта с помощью модуля Imp
Надеюсь, это поможет. Будьте ДАЛЕКО посоветовал , что вы вступаете в более тайные периметры питона программирования и что а) четкое понимание того, что вы действительно хотите достичь , и б) полное понимание последствий имеет важное значение.
источник