4

I am trying to patch an internal package function defined in the __init__.py that is being used by a function inside of a module inside of the same package. The problem that I am facing is that it does not get patched.

I've had some success when I've changed the import statement inside of the module that is using the function that needs to be patched to a absolute import. The problem is that I do not want an absolute import, refactoring code will be a pain that way.

The structure of my test setup is:

|- mylib
|  |- __init__.py
|  \- process.py
|- tests
|  \- test_process.py
|- setup.py

Init of the package

# __init__.py
def store_info(info):
    raise ValueError('No connection!')

Intended situation

# process.py
from . import store_info


def process_info(info):
    store_info(info)
# test_process.py
from unittest.mock import patch
import mylib.process


@patch('mylib.store_info')
def test_process_info(store_info_mock):
    info = "Some info"
    mylib.process.process_info(info)
    store_info_mock.assert_called_with(info)

When I've changed the import in the process.py from a relative one to a absolute import it works.

# process.py
import mylib


def process_info(info):
    mylib.store_info(info)

With the import statement like import mylib the test passes with the appropriate patched mock. Using a statement like from . import store_data the function does not gets patched.

Is there a possibility to use a relative import and still be able to patch a function within the same package? If so, what is a good practice for this?

blastbeat
  • 43
  • 3

1 Answers1

1

You are patching the function where it's declared; instead, you should patch the function where it's actually used. Change the decorator to

@patch('mylib.process.store_info')
def test_process_info(store_info_mock):
    ...

See Where to patch section from the stdlib's docs.

hoefling
  • 59,418
  • 12
  • 147
  • 194