Murtuza Z
Murtuza Z

Reputation: 6017

Mock method which returns same value passed as argument

How do I mock python method using python unittest.mock which will return same value passed as argument,

I tried,

from unittest.mock import MagicMock

def dummy_function(value):
    "Will return same value as value passed to the function"
    return value

# To moke gettext function used in template
# Then I pass this mock method to Jinja2 template to moke gettext string
_ = MagicMock(return_value=dummy_function)

When I print the jinja template it displays test something like below,

<div class="order_details">\n                
<legend class="badge">&lt;function dummy_function at 0x10887f730&gt;</legend>\n            
</div>\n 

Orignal Jinja2 template has

<div class="order_details">             
<legend class="badge">_('Details')</legend>           
</div>

Upvotes: 6

Views: 6922

Answers (2)

lee-pai-long
lee-pai-long

Reputation: 2282

You directly passed the function object as return value, that's why it prints the function's repr(name and memory address). You need to pass the actual value you want as return, so:

_ = MagicMock(return_value=dummy_function(somevalue))

But if the function always return the value passed it is useless, creating a mock is already enough so may be just do:

_ = MagicMock(return_value=somevalue)

Then call your mock as you would.

Sidenote: What is the purpose of the _ usage instead of a name? Are you mocking gettext ? If not or would be cleaner to give the mock a name, the best IMO is to name the mock like the real function you are mocking for explicitness.

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1121524

return_value is only ever a fixed object to return, and you just told the mock that the result of a call is a function object.

You want to use the side_effect attribute instead:

_ = MagicMock(side_effect=dummy_function)

Setting side_effect to a function causes it to be called with the same arguments as the mock. See the documentation:

If you pass in a function it will be called with same arguments as the mock and unless the function returns the DEFAULT singleton the call to the mock will then return whatever the function returns.

Demo:

>>> from unittest.mock import MagicMock
>>> identity = lambda a: a
>>> MagicMock(return_value=identity)('called')  # returns the function object, it won't call it
<function <lambda> at 0x10fa61620>
>>> MagicMock(side_effect=identity)('called')   # will call the function
'called'

Upvotes: 10

Related Questions