Jonas Geiregat
Jonas Geiregat

Reputation: 5442

Mock patch multiple

I'm trying to mock multiple functions inside a module, from within a TestCase:

from mock import patch, DEFAULT, Mock

function_a = Mock()
function_a.return_value = ['a', 'list'] 
with patch.multiple('target.module',
                    function_a=function_a,
                    function_b=DEFAULT) as (f_a, f_b):

To my surprise, this is not working, giving me the following Traceback:

ValueError: need more than 1 value to unpack

using: http://www.voidspace.org.uk/python/mock/

Upvotes: 4

Views: 8131

Answers (3)

Marc
Marc

Reputation: 5516

You can use Parenthesized Context Managers to patch multiple thing with Python 3.10 like so:

from unittest.mock import patch, DEFAULT, Mock

def setup():
    with (
        patch("target.module.function_a", Mock(), return_value = ['a', 'list']) as f_a,
        patch("target.module.function_b", DEFAULT) as f_b,
    ):
        # proceed to test

Upvotes: 1

Melvin
Melvin

Reputation: 1610

For patch.multiple, assigning the patched function name (function_a) to any value other than DEFAULT, or unittest.mock.DEFAULT, will result in the returned dictionary not containing the mocked function.

In other words,
with patch.multiple('target.module', func_a=SOME_VALUE, func_b=DEFAULT) as mocks: mocks['func_a'] # KeyError: 'func_a'

Also, assigning with patch.multiple(...) as (f_a, f_b) is going to give you two strings, which in your case will be 'function_a' and 'function_b'. This is equivalent to the operation

x = dict(function_a = MagicMock_a, function_b = MagicMock_b)
(f_a, f_b) = x
f_a    # 'function_a'

If you wish to access the MagicMock object, assign it to the dictionary value instead, something like mocks['func_a'] = f_a.

Upvotes: 5

Daniel Roseman
Daniel Roseman

Reputation: 600041

So, from that documentation page you link to:

If patch.multiple is used as a context manager, the value returned by the context manger is a dictionary where created mocks are keyed by name

But you've got with patch.multiple(...) as (f_a, f_b) - two values. Looks like it should be with patch.multiple(...) as fdict, and fdict will be a dictionary with keys function_a and function_b.

Upvotes: 3

Related Questions