pythonpython-3.xpytestpython-unittestpython-unittest.mock

Function not being mocked unless full path is called


main.py

from path.to.mod import run

def foo(args: str):
    run(args)

test.py

@patch("path.to.mod.run")
def verify_args(mock):
    foo("bar")
    mock.assert_called_once_with("bar")

the above code does not mock run ie assertion fails.
However if I change main.py to

def foo(args: str):
    path.to.mod.run(args)

then the test mocks successfully

How can I mock without needing specify full path from main.py?

if I change test.py to

from path.to.mod import run
@patch("run")
def verify_args(mock):
    foo("bar")
    mock.assert_called_once_with("bar")

it complains that run is not a valid target

TypeError: Need a valid target to patch. You supplied: 'run'

Solution

  • If anyone else is having the same problem/confusion, the documentation says:

    The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.

    So in test.py I had to mock main.run (where it is looked up) and not path.to.mod.run (where it is defined).