[TIP] Return different values based on an argument passed to a method

Marcin Zajączkowski mszpak at wp.pl
Mon Mar 5 13:33:29 PST 2012


On 2012-03-05 18:01, Michael Foord wrote:
> On 05/03/2012 16:49, Marcin Zajączkowski wrote:
>> Dnia 5-03-2012 o godz. 13:41 Michael Foord napisał(a):
>>> On 05/03/2012 12:33, Marcin Zajączkowski wrote:
>>>> Hi,
>>>>
>>>> Is it possible to simple stub a method's return value when called with
>>> an argument (any argument or specific one)?
>>>> I tried with:
>>>> mock = Mock()
>>>> mock.foo(ANY).return_value(False)
>>>>
>>>> but in a debugger I see that in my code mock.foo(<<some_object>>)
>>> returns a mock instead of False value. If not the returning value I
>>> could use assert_called_with with custom mather, but how to return
>>> different value based on an argument?
>>>
>>> To change the return value of mock.foo you set mock.foo.return_value.
>>>
>>> mock.foo(ANY).return_value(False)  is fetching the return_value mock got
>>> by calling mock.foo - and then calling that mock with False! (You're not
>>> setting any return_value at all, you're just making calls.)
>>>
>>> To have mock.foo return False, do this:
>>>
>>>       mock.foo.return_value = False
>> Thanks for your quick reply! Your solution worked. I am a Java guy and
>> referencing to a method without brackets is very intuitive :).
>>
>>> It's not entirely clear to me from your post, but if you want to you can
>>> dynamically change the value returned from a call using side_effect.
>>>
>>>   >>>  from mock import MagicMock
>>>   >>>  def side_effect(arg):
>>> ...      if arg == 1:
>>> ...          return False
>>> ...      return True
>>> ...
>>>   >>>  m = MagicMock()
>>>   >>>  m.foo.side_effect = side_effect
>>>   >>>  m.foo(1)
>>> False
>>>   >>>  m.foo(37)
>>> True
>> It wasn't very precisely in my first mail. A separate function can be
>> useful when you have non trivial logic inside. But maybe it is
>> possible to override the default value returned by mock only for
>> specific (simple) cases in a shorter way?
>>
>> For example. Only when foo method called with argument 5 return "you
>> win". Something like (example from Java):
>> when(m.foo(5)).willReturn("you win");
>> (in other cases return default value)
> 
> If you want the "standard" return value, then you can have your
> side_effect return DEFAULT. So this:
> 
>>>> from mock import MagicMock, DEFAULT
>>>> def side_effect(arg):
> ...      if arg == 5:
> ...          return 'you win'
> ...      return DEFAULT
> ...
>>>> m = MagicMock()
>>>> m.foo.side_effect = side_effect

Thanks Micheal.

Regards
Marcin

-- 
http://blog.solidsoft.info/ - Working code is not enough



More information about the testing-in-python mailing list