Search code examples
pythonpython-mock

How to determine if method is called using Python mock but does not replace the function body?


There are plenty of examples that shows how to assert a method has been called using Mock, eg. assert_called_with(), but all of them involve replacing the method with Mock instance.

What I want is a little bit different, I want the function to be executed normally without its body replaced, but still want to assert if the function has been called.

eg.

def dosomething(...)
    # creates records that I will test later on.
    ....

def execute():
    ....
    dosomething()

in my tests


def test_a(...):
    with patch(dosomething...) as mocked:
        execute()
        mocked.assert_called_with()

I know I can test against the records that dosomething() creates instead. Yes I agree, but I just want to find out if it's possible to do per as my question.


Solution

  • Use Mock's wraps kwarg and pass it the original method.

    For example,

    >>> from unittest import mock
    >>> def hi(name): print('hi', name)
    >>> mock_hi = mock.Mock(wraps=hi)
    

    The wrapped function is called by the mock.

    >>> mock_hi('Bob')
    hi Bob
    

    But it's still a mock that remembers calls.

    >>> mock_hi.call_args_list
    [call('Bob')]
    

    Recall that patch() will pass along extra kwargs to the Mock it makes, so you can use the wraps argument here too. For example,

    >>> with mock.patch('builtins.float', wraps=float) as mock_float:
    ...     x = float('inf')
    ...     print(x)  # If we hadn't wrapped, x would be a mock.
    ...     print(mock_float.call_args_list)
    ...
    inf
    [call('inf')]