findissuefixit
findissuefixit

Reputation: 121

python mocking a function call during module import in test file

I'm trying to mock a function call that executes when a module is imported, below is the sample of the issue that I'm having

app/module.py

    from util import get_param 

    PARAM = get_param('param_name')
    class sample():
         def run_sample(self):
             print(PARAM)

app/tests/test_module.py

from app import module
import unittest

class TestSample(unittest.TestCase):
    @mock.patch('app.module.get_param')
    def test_run_sample(self, mock_get_param):
        test_obj = module.sample()
        test_obj.run_sample()

This doesn't work and it calls the original get_param method instead of mocking it.

Upvotes: 2

Views: 941

Answers (2)

musingsole
musingsole

Reputation: 1227

I believe your mock path is correct, but you've already imported the module in your test. So, when your test is instantiated, this get_param function has already been called. For this mock to work, you need to move your import statement into the test.

Upvotes: 1

Siddhant Kumar
Siddhant Kumar

Reputation: 21

I had recently been in this situation, the solution I went with was a bit hacky and involved modifying the internal module cache.

#define mocked symbol
get_param = Mock()

class TestSample:

    @pytest.fixture
    def import_time_mock(self):
      # Trick python into thinking current test-file is target module
      orig = sys.modules["app.module"]
      sys.modules["app.module"] = sys.modules[__name__]

      nonlocal get_param 
      yield get_param

      # Restore modules cache
      sys.modules["app.module"] = orig

    def test_run_sample(self, import_time_mock):
        from app import module

        test_obj = module.sample()
        test_obj.run_sample()

Upvotes: 2

Related Questions