Reputation: 449
I'm trying to mock a function that looks like this [example]:
def f(overwrite=False):
if overwrite:
return "overwritten"
else:
return "skipping"
with a unittest.mock.Mock
object that looks like this:
from unittest.mock import Mock, patch
mock_f = Mock(return_value = 'default', side_effect = lambda overwrite: 'overwrite' if overwrite else 'no overwrite')
#mock_f.func_defaults = (False,)
mock_f.__defaults__ = (False,)
mock_f()
The code above gives me an error (TypeError: <lambda>() missing 1 required positional argument: 'overwrite'
)
Since f
itself can be called without supplying arguments, I need to be able to call mock_f()
without arguments. However, if I try to call mock_f(True)
or mock_f(False)
it works fine. It doesn't work neither with mock_f.func_defaults
nor with mock_f.__defaults__
.
How should this be done?
Upvotes: 0
Views: 910
Reputation: 4964
Use wraps
to wrap f
with a mock but still execute the real methods:
from unittest.mock import patch
def f(overwrite=False):
if overwrite:
return "overwritten"
else:
return "skipping"
with patch('__main__.f', wraps=f) as mock_f:
print(mock_f())
print(mock_f(True))
print(mock_f(False))
Output:
skipping
overwritten
skipping
Upvotes: 1
Reputation: 16805
The side_effect has to have the same signature as the function it replaces, if used this way (e.g. if assigned a function object). That means that you have to adapt the side_effect, not the mock:
>>> mock_f = Mock(return_value='default', side_effect=lambda
... overwrite=False: 'overwrite' if overwrite else 'no overwrite')
>>> mock_f()
no overwrite
Upvotes: 2