I'd like to modify the arguments passed to a method in a module, as opposed to replacing its return value.
I've found a way around this, but it seems like something useful and has turned into a lesson in mocking.
from third_party import ThirdPartyClass ThirdPartyClass.do_something('foo', 'bar') ThirdPartyClass.do_something('foo', 'baz')
@mock.patch('module.ThirdPartyClass.do_something') def test(do_something): # Instead of directly overriding its return value # I'd like to modify the arguments passed to this function. # change return value, no matter inputs do_something.return_value = 'foo' # change return value, based on inputs, but have no access to the original function do_something.side_effect = lambda x, y: y, x # how can I wrap do_something, so that I can modify its inputs and pass it back to the original function? # much like a decorator?
I've tried something like the following, but not only is it repetitive and ugly, it doesn't work. After some PDB introspection.. I'm wondering if it's simply due to however this third party library works, as I do see the original functions being called successfully when I drop a pdb inside the side_effect
.
Either that, or some auto mocking magic I'm just not following that I'd love to learn about.
def test(): from third_party import ThirdPartyClass original_do_something = ThirdPartyClass.do_something with mock.patch('module.ThirdPartyClass.do_something' as mocked_do_something: def side_effect(arg1, arg2): return original_do_something(arg1, 'overridden') mocked_do_something.side_effect = side_effect # execute module.py
Any guidance is appreciated!
Mock functions, also known as spies, are special functions that allow us to track how a particular function is called by external code. Instead of just testing the output of the function, we can gain additional information about how a function was used.
The simplest and most common way of creating a mock is jest. fn() method. If no implementation is provided, it will return the undefined value. There is plenty of helpful methods on returned Jest mock to control its input, output and implementation.
side_effect: A function to be called whenever the Mock is called. See the side_effect attribute. Useful for raising exceptions or dynamically changing return values. The function is called with the same arguments as the mock, and unless it returns DEFAULT , the return value of this function is used as the return value.
How do we mock in Python? Mocking in Python is done by using patch to hijack an API function or object creation call. When patch intercepts a call, it returns a MagicMock object by default. By setting properties on the MagicMock object, you can mock the API call to return any value you want or raise an Exception .
You may want to use parameter wraps
for the mock call. (Docs for reference.) This way the original function will be called, but it will have everything from Mock interface.
So for changing parameters called to original function you may want to try it like that:
org.py
:
def func(x): print(x)
main.py
:
from unittest import mock import org of = org.func def wrapped(a): of('--{}--'.format(a)) with mock.patch('org.func', wraps=wrapped): org.func('x') org.func.assert_called_with('x')
result:
--x--
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With