Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python Mock patch.multiple argument names

It's possible to change the test argument name of a patched class or function when using patch as a decorator.

@patch('module.ClassName2')
@patch('module.ClassName1')
def test(MockClass1, MockClass2):
    MockClass1.test.return_value = 'testing'

However, I can't seem to find in the documentation how to differentiate the original object and the mock when using patch.multiple.

@patch.multiple('module.ClassName', foo=DEFAULT, bar=DEFAULT)
def test(foo, bar):
    foo.return_value = 'foo'

In the above example, the arguments in the test must be foo and bar. Is there any clean way to allow their use with a clearer differentiation, e.g. mock_foo?

This would also be handy in cases where the original class or method is needed in part of the test, avoiding imports like from module import Class as OriginalClass

Thanks in advance.

like image 426
Ben Murden Avatar asked Mar 18 '23 05:03

Ben Murden


1 Answers

No and ... yes:

  • No because if you take a look to mock source code you will see that there is no way to change attribute_name
  • Yes because they are passed as keyword args and so they are embedded in keywords args dictionary: so you can extract them from dictionary as you want.

Follow a simple example of how you can do it... I know that maybe was not exactly what you are looking for but it is the only way to do it.

@patch.multiple('module.ClassName', foo=DEFAULT, bar=DEFAULT)
def test(**mocks):
    mock_foo, mock_bar = mocks["foo"], mocks["bar"]
    mock_foo.return_value = 'foo'
    mock_bar.return_value = 'bar'

If you use patch.multiple as context manager that is the only way to get the mocks, so the two way are consistent

def test():
    with patch.multiple('module.ClassName', foo=DEFAULT, bar=DEFAULT) as mocks:
        mock_foo, mock_bar = mocks["foo"], mocks["bar"]
        mock_foo.return_value = 'foo'
        mock_bar.return_value = 'bar'
like image 91
Michele d'Amico Avatar answered Mar 27 '23 15:03

Michele d'Amico