-1

Suppose I have a file called a.py with code like

import mod1
mod1.a()

def b():
   print("hi")

Now if I want to mock fun b() then unittest.py while have import statement at top like

from a import b

at time of import mod1.a() will be called. How can I mock that call which is happening at the time of import.

progmatico
  • 4,714
  • 1
  • 16
  • 27
shivams
  • 2,597
  • 6
  • 25
  • 47

1 Answers1

2

Consider removing code from module top-level, by moving it to a block protected by

if __name__ == '__main__':
    mod1.a()
    ... # the rest of your top level code

This way the protected code does not get executed on imports, only when run directly.

If you still need the call there and want to mock it, it is very simple. With files like this,

# mod.py

import mod1
mod1.a()

def b():
   print("hi")


# mod1.py

def a():
    print('Running a!')

# test_1.py
# Note: do not call unittest.py to a file.
# That is the name of a module from the Python stdlib,
# you actually need to use it and things will not work,
# because Python tries to load your file not the library you need.

from unittest.mock import patch

with patch('mod1.a') as mock_a:
    ... # configure mock_a here if there is a need, for example
        # to set a fake a call result
    import mod
    ... # the rest of your testing code. Use `mock_a` if you want to
        # inspect `a` calls.

Outside the with mod1.a is no longer mocked. There are other ways to start and stop mocking, you should look into the documentation. Before studying mock make sure you understand well how unittests work and how you can organize your tests.

progmatico
  • 4,714
  • 1
  • 16
  • 27
  • I understand but I want that function call to happen on import. – shivams Dec 20 '19 at 06:16
  • I am pretty sure that when executing the `patch('mod1.a')`, the module will be loaded to check that it contains what you want to patch, which will trigger the not mocked call before patching it. – Dani bISHOP Jan 25 '22 at 10:16