Search code examples
pythonunit-testingpython-2.7monkeypatchingpython-mock

mock.patch() not patching class who called a couples of levels inside function call


I have a task

def task():
   a = worker()
   a.do_some_work()

Worker itself is a separate class in separate module, who use Driver class like that,

class Worker(object):
   def __init__(self):
     self.driver = Driver(args)
     ...

and once again Driver is a separate class in separate module

so when I trying something like

with patch('package.module.Driver', new=Mock(return_value=999)):
   task()

in task there is still a Driver class instance, but not a mock. That's wrong. How to fix that?

UPD1: Driver and Worker live in different modules and Worker import Driver


Solution

  • Your MyProject.Workers.base module imported Driver as a global:

    from MyProject.utils.drivers import Driver
    

    This is a new, separate reference to the Driver class. If you now patch MyProject.utils.drivers.Driver, the Worker class will not see the patched object; as it'll use it's own global reference.

    Patch the global Worker actually uses:

    with patch('MyProject.Workers.base.Driver', new=Mock(return_value=999)):
        task()
    

    See the Where to patch section of the mock documentation.