Насмешливая функция python на основе входных аргументов
мы использовали Mock для python на некоторое время.
теперь у нас есть ситуация, в которой мы хотим издеваться над функцией
def foo(self, my_param):
#do something here, assign something to my_result
return my_result
обычно, способ издеваться над этим был бы (предполагая, что foo является частью объекта)
self.foo = MagicMock(return_value="mocked!")
даже, если я позвоню foo () пару раз я могу использовать
self.foo = MagicMock(side_effect=["mocked once", "mocked twice!"])
теперь я столкнулся с ситуацией, в которой я хочу вернуть фиксированное значение, когда входной параметр имеет определенное значение. Так что если скажем "my_param" равно "что-то", то я хочу вернуть "my_cool_mock"
это, кажется, доступно на mockito для python
when(dummy).foo("something").thenReturn("my_cool_mock")
Я искал о том, как достичь того же с Mock без успеха?
какие идеи?
5 ответов:
если
side_effect
является функцией, то все, что возвращает эта функция что зовет к мнимому возвращению. Элементside_effect
функция вызывается с те же аргументы, что и у макета. Это позволяет варьировать возврат значение вызова динамически, на основе входных данных:>>> 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)]
Как указано в Python макет объекта с методом вызывается несколько раз
решение состоит в том, чтобы написать свой собственный 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
это делает трюк
побочный эффект принимает функцию (которая также может быть функция Lambda), поэтому для простых случаев вы можете использовать:
m = MagicMock(side_effect=(lambda x: x+1))
просто чтобы показать другой способ сделать это:
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
Я знаю, что это довольно старый вопрос, может помочь в качестве улучшения с помощью 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