Comment simuler une importation, (simuler A.B) ?
Le module A comprend l'importation B à son sommet.
C'est facile, il suffit de simuler la bibliothèque dans sys.modules avant qu'elle ne soit importée :
if wrong_platform():
sys.modules['B'] = mock.MagicMock()
et ensuite, tant que A
ne dépend pas de types spécifiques de données renvoyées par les objets de B :
import A
devrait fonctionner.
Vous pouvez également simuler import A.B
:
Cette méthode fonctionne même si vous avez des sous-modules, mais vous devrez simuler chaque module. Disons que vous avez ceci :
from foo import This, That, andTheOtherThing
from foo.bar import Yada, YadaYada
from foo.baz import Blah, getBlah, boink
Pour simuler, il suffit de faire ce qui suit avant d'importer le module qui contient ce qui précède :
sys.modules['foo'] = MagicMock()
sys.modules['foo.bar'] = MagicMock()
sys.modules['foo.baz'] = MagicMock()
(Mon expérience : J'avais une dépendance qui fonctionnait sur une plateforme, Windows, mais qui ne fonctionnait pas sur Linux, où nous effectuons nos tests quotidiens. J'avais donc besoin de simuler la dépendance pour nos tests. Heureusement, c'était une boîte noire, donc je n'ai pas eu besoin de mettre en place beaucoup d'interaction).
Se moquer des effets secondaires
Addendum : En fait, j'avais besoin de simuler un effet secondaire qui prenait du temps. J'avais donc besoin que la méthode d'un objet dorme pendant une seconde. Cela fonctionnerait comme ceci :
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)
Et puis le code prend un certain temps pour s'exécuter, tout comme la vraie méthode.