基于input参数嘲笑python函数

我们一直在使用Mock for python。

现在,我们有一个想嘲笑一个function的情况

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!"]) 

现在,我面临的情况是,当input参数具有特定的值时,我想返回一个固定值。 所以,如果让我们说“my_param”等于“东西”,那么我想返回“my_cool_mock”

这似乎是在Python的mockito上可用

 when(dummy).foo("something").thenReturn("my_cool_mock") 

我一直在寻找如何达到与Mock一样没有成功?

有任何想法吗?

如果side_effect是一个函数,那么无论函数返回什么调用模拟返回。 side_effect函数被调用与模拟相同的参数。 这允许您根据inputdynamic地改变呼叫的返回值:

 >>> 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)] 

http://www.voidspace.org.uk/python/mock/mock.html#calling

正如在Python Mock对象中用多次调用的方法所表明的那样

一个解决scheme是写我自己的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