Skip to content
Advertisement

How to patch an object instantiated outside of a function to reuse in every test python

I have a module where I instantiate an object outside of my functions, so I can reuse it:

from somewhere import client

client_obj = client()

def function_with_client1():
    client_obj.foo1()

def function_with_client2()
    client_obj.foo2()

I want to patch this client once so that in my tests I can reuse it across multiple tests, like so:

from unittest.mock import patch
from above import client, function_with_client1, function_with_client2

mocked_client = patch('above.client') #this doesn't work

def test_function_with_client1():
    function_with_client1()

def test_function_with_client2():
    function_with_client2()

The above patch doesn’t work, it runs the tests with the real object instance. How can I correctly patch this in my test file once, so that the tests reuse it across all tests? I know I can decorate each test with a patch, however I want to reuse the same patched object like I do in my real module

Advertisement

Answer

Patching global objects is always a problem as they are initialized before patching. This can be worked around by reloading the module after patching, but the better solution is not to do the inialization globally.

You can use some kind of lazy initialization, a simple implementation would be something like this:

from somewhere import client

client_obj = None

def get_client():
    global client_obj
    if not client_obj:
        client_obj = client()
    return client_obj

def function_with_client1():
    get_client().foo1()

...

Now client() is not called on importing the module, and you can mock it in your test.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement