Using Python unittest patch with side_effect, how you can get the the exact thing that the mock returned?

34 views Asked by At

Let's imagine we have some base class that holds some common logic and then some instances to that base class for solving some specific problems.

We also have some interface function that returns the appropriate instance for the current problem.

In tests, I want to access the exact instance that Python unittest patch decorator used when patching the original interface when the test is run via the parameter `mocked_do_stuff` that the test itself accepted.

Let's have something like this:

from unittest import TestCase
from unittest.mock import patch


class MockerObjectInstance:

    def __init__(self):
        self._counter = 0

    def do_stuff(self):
        self._counter += 1


def mock_function(*args, **kwargs):
    return MockerObjectInstance()


class TestSomething(TestCase):

    @patch('path.to.original.interface.function', side_effect=mock_function)
    def test_do_stuff_call_times(self, mocked_do_stuff):
        # Do some tests that access original < do_stuff >
        
        # get exact < MockerObjectInstance > that < mock_function > returned 
        # via the parameter < mocked_do_stuff > and assert counter was 
        # specific number, for example       

The only way I could do this is by having a global parameter that holds the last instance and then accees that in test.

Here is the modified mock_function that worked.

GLOBAL_PARAMETER = None
def mock_function(*args, **kwargs):
    instance = MockerObjectInstance()
    global GLOBAL_PARAMETER
    GLOBAL_PARAMETER = instance
    return instance

But I am not that keen into that solution for using the global variables which is a bad practice. Although, the global parameter will be updated for every test.

0

There are 0 answers