Home > front end >  Python mock issue when mocking a dependency outside a method
Python mock issue when mocking a dependency outside a method

Time:09-23

Scenario 1

I have the following code I am trying to mock the function setup_logger() but if the logger is declared outside the function I am getting an error.

The source file my_source.py:

from pda.utils.logging import setup_logger


logger = setup_logger()

def some_method():
  some_code

The test file test_my_source.py:

from unittest.mock import patch
import pytest
from src.my_source import some_method

def test_some_method():
    with patch('src.my_source.setup_logger') as mock:
        some_method()

In the above scenario, I am getting the below strange errors:

_
tests/test_my_source.py:3: in <module>
    from src.my_source import some_method
src/my_source.py:8: in <module>
    logger = setup_logger()
/conda_envs/test_env/lib/python3.6/site-packages/pda/utils/logging.py:79: in setup_logger
    base_conf = get_config()
/conda_envs/test_env/lib/python3.6/site-packages/pda/utils/generics.py:285: in get_config
    tmp_path = os.path.join(tmp_path, name)
/conda_envs/test_env/lib/python3.6/posixpath.py:80: in join
    a = os.fspath(a)
E   TypeError: expected str, bytes or os.PathLike object, not NoneType
=================================================================== short test summary info ====================================================================
ERROR tests/test_my_source.py - TypeError: expected str, bytes or os.PathLike object, not NoneType

Scenario 2

If I change the source code and the test then it works. The source file my_source.py"

from pda.utils.logging import setup_logger


def some_method():
  logger = setup_logger()
  some_code

The test file test_my_source.py:

from unittest.mock import patch
import pytest
from src.my_source import some_method

def test_some_method():
    with patch('src.my_source.setup_logger') as mock:
        some_method()

Changing the source code is not an option as in scenario 2 and I have to work with scenario 1. Do I have to modify the test in scenario 1 or what can be the issue?

CodePudding user response:

The following line in my_source.py:

logger = setup_logger()

is executed when you import src.my_source, before you patch setup_logger.

You can instead import src.my_source after patching setup_logger:

from unittest.mock import patch
import pytest

def test_some_method():
    with patch('src.my_source.setup_logger') as mock:
        from src.my_source import some_method
        some_method()

CodePudding user response:

With the help of the answer from blhsing I fix the issue by patching the method where it is defined like this:

def test_some_method():
    with patch('pda.utils.logging.setup_logger') as mock:
        from src.my_source import some_method
        some_method()

Alternatively, we can also patch if there is more than one method using:

    mock_method1 = mock.patch('pda.utils.logging.setup_logger').start()
    some_method()
    mock_method.stop()
  • Related