Nous utilisons Mock for python depuis un moment.
Maintenant, nous avons une situation dans laquelle nous voulons nous moquer d’une fonction
def foo(self, my_param): #do something here, assign something to my_result return my_result
Normalement, la façon de se moquer de cela serait (en supposant que foo faisant partie d’un object)
self.foo = MagicMock(return_value="mocked!")
Même si j’appelle foo () plusieurs fois, je peux utiliser
self.foo = MagicMock(side_effect=["mocked once", "mocked twice!"])
Maintenant, je suis confronté à une situation dans laquelle je veux retourner une valeur fixe lorsque le paramètre d’entrée a une valeur particulière. Donc, si nous disons “mon_param” est égal à “quelque chose” alors je veux retourner “my_cool_mock”
Cela semble être disponible sur mockito pour python
when(dummy).foo("something").thenReturn("my_cool_mock")
J’ai cherché à obtenir la même chose avec Mock sans succès?
Des idées?
Si
side_effect
est une fonction, quel que soit le retour de cette fonction, quels sont les appels à la simulation. La fonctionside_effect
est appelée avec les mêmes arguments que le simulacre. Cela vous permet de varier dynamicment la valeur de retour de l’appel, en fonction de l’entrée:>>> def side_effect(value): ... return value + 1 ... >>> m = MagicMock(side_effect=side_effect) >>> m(1) 2 >>> m(2) 3 >>> m.mock_calls [call(1), call(2)]
Comme indiqué à l’ object Python Mock avec la méthode appelée plusieurs fois
Une solution consiste à écrire mon propre side_effect
def my_side_effect(*args, **kwargs): if args[0] == 42: return "Called with 42" elif args[0] == 43: return "Called with 43" elif kwarg['foo'] == 7: return "Foo is seven" mockobj.mockmethod.side_effect = my_side_effect
Ça fait le tour
L’effet secondaire prend une fonction (qui peut aussi être une fonction lambda ), donc pour des cas simples, vous pouvez utiliser:
m = MagicMock(side_effect=(lambda x: x+1))
Juste pour montrer une autre façon de le faire:
def mock_isdir(path): return path in ['/var/log', '/var/log/apache2', '/var/log/tomcat'] with mock.patch('os.path.isdir') as os_path_isdir: os_path_isdir.side_effect = mock_isdir
Je sais que c’est une question assez ancienne, pourrait aider comme une amélioration en utilisant python lamdba
self.some_service.foo.side_effect = lambda *args:"Called with 42" \ if args[0] == 42 \ else "Called with 42" if args[0] == 43 \ else "Called with 43" if args[0] == 43 \ else "Called with 45" if args[0] == 45 \ else "Called with 49" if args[0] == 49 else None