Mocking python function based on input arguments
Side effect takes a function (which can also be a lambda function), so for simple cases you may use:
m = MagicMock(side_effect=(lambda x: x+1))
As indicated at Python Mock object with method called multiple times
A solution is to write my own 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 kwargs['foo'] == 7:
return "Foo is seven"
mockobj.mockmethod.side_effect = my_side_effect
That does the trick
If you "want to return a fixed value when the input parameter has a particular value", maybe you don't even need a mock and could use a dict
along with its get
method:
foo = {'input1': 'value1', 'input2': 'value2'}.get
foo('input1') # value1
foo('input2') # value2
This works well when your fake's output is a mapping of input. When it's a function of input I'd suggest using side_effect
as per Amber's answer.
You can also use a combination of both if you want to preserve Mock
's capabilities (assert_called_once
, call_count
etc):
self.mock.side_effect = {'input1': 'value1', 'input2': 'value2'}.get
If
side_effect_func
is a function then whatever that function returns is what calls to the mock return. Theside_effect_func
function is called with the same arguments as the mock. This allows you to vary the return value of the call dynamically, based on the input:>>> def side_effect_func(value): ... return value + 1 ... >>> m = MagicMock(side_effect=side_effect_func) >>> m(1) 2 >>> m(2) 3 >>> m.mock_calls [call(1), call(2)]
http://www.voidspace.org.uk/python/mock/mock.html#calling