Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking python function based on input arguments

We have been using Mock for python for a while.

Now, we have a situation in which we want to mock a function

def foo(self, my_param):     #do something here, assign something to my_result     return my_result 

Normally, the way to mock this would be (assuming foo being part of an object)

self.foo = MagicMock(return_value="mocked!") 

Even, if i call foo() a couple of times i can use

self.foo = MagicMock(side_effect=["mocked once", "mocked twice!"]) 

Now, I am facing a situation in which I want to return a fixed value when the input parameter has a particular value. So if let's say "my_param" is equal to "something" then I want to return "my_cool_mock"

This seems to be available on mockito for python

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

I have been searching on how to achieve the same with Mock with no success?

Any ideas?

like image 432
Juan Antonio Gomez Moriano Avatar asked Apr 23 '13 05:04

Juan Antonio Gomez Moriano


2 Answers

If side_effect_func is a function then whatever that function returns is what calls to the mock return. The side_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

like image 73
Amber Avatar answered Sep 21 '22 17:09

Amber


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

like image 27
Juan Antonio Gomez Moriano Avatar answered Sep 24 '22 17:09

Juan Antonio Gomez Moriano