Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to access the original function in a mocked method/function such that I can modify the arguments and pass it to the original functions?

Tags:

python

mocking

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.

module.py

from third_party import ThirdPartyClass  ThirdPartyClass.do_something('foo', 'bar') ThirdPartyClass.do_something('foo', 'baz') 

tests.py

@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!

like image 620
Yuji 'Tomita' Tomita Avatar asked May 19 '15 21:05

Yuji 'Tomita' Tomita


People also ask

What does it mean to mock a function?

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.

How do you mock a method in jest?

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.

What is Side_effect in mock python?

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 you mock a function in Python?

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 .


1 Answers

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-- 
like image 86
Pax0r Avatar answered Sep 23 '22 10:09

Pax0r