Jak mockować import (mock AB)?
Moduł A zawiera import B u góry.
Łatwo, po prostu mock bibliotekę w sys.modules, zanim zostanie zaimportowana:
if wrong_platform():
sys.modules['B'] = mock.MagicMock()
a następnie, o ile A
nie polega na określonych typach danych zwracanych z obiektów B:
import A
powinno po prostu działać.
Możesz też kpić z import A.B
:
Działa to nawet, jeśli masz podmoduły, ale będziesz chciał mockować każdy moduł. Powiedz, że masz to:
from foo import This, That, andTheOtherThing
from foo.bar import Yada, YadaYada
from foo.baz import Blah, getBlah, boink
Aby wyszydzić, po prostu wykonaj poniższe czynności, zanim zaimportowany zostanie moduł zawierający powyższe:
sys.modules['foo'] = MagicMock()
sys.modules['foo.bar'] = MagicMock()
sys.modules['foo.baz'] = MagicMock()
(Moje doświadczenie: miałem zależność, która działa na jednej platformie, Windows, ale nie działała na Linuksie, gdzie przeprowadzamy nasze codzienne testy. Musiałem więc sfałszować zależność dla naszych testów. Na szczęście była to czarna skrzynka, więc Nie musiałem konfigurować wielu interakcji).
Kpiące efekty uboczne
Dodatek: Właściwie potrzebowałem zasymulować efekt uboczny, który zajął trochę czasu. Więc potrzebowałem metody obiektu, aby zasnąć przez sekundę. To działałoby tak:
sys.modules['foo'] = MagicMock()
sys.modules['foo.bar'] = MagicMock()
sys.modules['foo.baz'] = MagicMock()
# setup the side-effect:
from time import sleep
def sleep_one(*args):
sleep(1)
# this gives us the mock objects that will be used
from foo.bar import MyObject
my_instance = MyObject()
# mock the method!
my_instance.method_that_takes_time = mock.MagicMock(side_effect=sleep_one)
A potem kod zajmuje trochę czasu, tak jak prawdziwa metoda.
Mock
nie poprawi to niektórych magicznych atrybutów (__%s__
), takich jak__name__
.