Mock function called on import

Question:

I have a module I need to test that calls a function on import but I cannot call this function for various reasons. So I am mocking this function but even mocking it calls import.

For example I am testing mod1.py that looks like this:

import os

def bar():
    return 'foo'

def dont_call():
    os.listdir("C:\tmp")

dont_call()

And my test looks something like this:

import mock

@mock.patch("mod1.dont_call")
def test_mod1(mock_dont_call):
    import mod1
    assert mod1.bar()=='foo'

if __name__=="__main__":
    test_mod1()

The problem is os.listdir is called.

I cannot change mod1 so what can I do?

I am using python2.7.

To put this in context I am testing a module that opens a database connection on import which I do not agree with but I can see the reasoning behind it. Unfortunately I cannot access this database on my QA machine.

Asked By: vfxGer

||

Answers:

If you want code to ‘not’ be executed on import put them inside the following condition:

In mod1.py, do the following:

if __name__=="__main__":
    dont_call()

This is because, by default when you import a python module, all the code in it gets executed. By adding the above condition, you are explicitly stating that dont_call() is to be called only when the file it run as a script and not when it is imported in other modules.

Answered By: Alagappan Ramu

The workaround I found was to mock what dont_call was calling giving me something like this:

import mock

@mock.patch("os.listdir")
def test_mod1(mock_dont_call):
    import mod1
    assert mod1.bar()=='foo'

if __name__=="__main__":
    test_mod1()
Answered By: vfxGer

Generally add function_path from its root instead from module.
e.g.
mod1.py

import os

def bar():
    return 'foo'

def dont_call():
    os.listdir("C:\tmp")

dont_call()

xyz.py
`
import mock

@mock.patch("os.listdir")
def test_mod1(mock_dont_call):
    import mod1
assert mod1.bar()=='foo'

if __name__=="__main__":
    test_mod1()
Answered By: Shreyas dantkale
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.