Como zombar de uma importação, (zombar AB)?
O módulo A inclui a importação B na parte superior.
Fácil, basta zombar da biblioteca em sys.modules antes de ser importada:
if wrong_platform():
sys.modules['B'] = mock.MagicMock()
e, desde A
que não dependa de tipos específicos de dados retornados dos objetos de B:
import A
deve funcionar.
Você também pode zombar import A.B
:
Isso funciona mesmo se você tiver submódulos, mas você deseja zombar de cada módulo. Digamos que você tenha o seguinte:
from foo import This, That, andTheOtherThing
from foo.bar import Yada, YadaYada
from foo.baz import Blah, getBlah, boink
Para zombar, basta fazer o seguinte antes que o módulo que contém os itens acima seja importado:
sys.modules['foo'] = MagicMock()
sys.modules['foo.bar'] = MagicMock()
sys.modules['foo.baz'] = MagicMock()
(Minha experiência: eu tinha uma dependência que funciona em uma plataforma, Windows, mas não funcionava no Linux, onde executamos nossos testes diários. Então, eu precisava zombar da dependência de nossos testes. Felizmente, era uma caixa preta, então Não precisei criar muita interação.)
Zombando de efeitos colaterais
Adendo: Na verdade, eu precisava simular um efeito colateral que levou algum tempo. Então, eu precisava do método de um objeto para dormir por um segundo. Isso funcionaria assim:
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)
E então o código leva algum tempo para ser executado, assim como o método real.
Mock
não irá corrigir alguns atributos mágicos (__%s__
) como__name__
.