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.