Maxim L
Maxim L

Reputation: 209

How to ignore certain Python modules on import?

I am trying to perform unit tests using Pytest on some of my code. The tests are being run in a separate Conda environment on a Docker. I would like to test certain functionalities of my code but cannot install all the modules of my code, because of the complexity of the installation of some of these modules and the time it would take to run.

How can I import only certain modules from a file, without needing the other modules installed?

If I try running a test, whilst importing a module from a file, my test fails since it cannot import the other modules.

Below is a mock-up of my file system:

test_file.py

from other_file import afunction

def this_test():
    assert afunction(2, 2) == 4

other_file.py

import math
import large_program

def afunction(x,y):
    return math.pow(x, y)

def anotherfunc():
    return large_program()

If I run Pytest, I will get:

 E   ImportError: No module named 'large_program'

Upvotes: 2

Views: 5562

Answers (3)

Dharmik Patel
Dharmik Patel

Reputation: 41

you can simply use MagicMock like this as well

from unittest.mock import MagicMock
import sys
sys.modules['large_program'] = MagicMock()

from other_file import afunction

def this_test():
    assert afunction(2, 2) == 4

Upvotes: 0

Felix
Felix

Reputation: 436

I liked the idea of cristid9 of mocking and combined it with dano's post here. I created an empty file called "nothing.py" that will replace the "large_program" with a unittest mock: test_file.py

import unittest.mock as mock
import nothing

with mock.patch.dict('sys.modules', large_program=nothing):
    from other_file import afunction

def this_test():
    assert afunction(2, 2) == 4

The other_file.py looks still like this

import math
import large_program

def afunction(x,y):
    return math.pow(x, y)

def anotherfunc():
    return large_program()

You can also apply the with statement on multiple modules:

other_file.py

import math
import large_program
import even_larger_program

def afunction(x,y):
    return math.pow(x, y)

def anotherfunc():
    return large_program()

test_file.py

import unittest.mock as mock
import nothing

with mock.patch.dict('sys.modules', large_program=nothing), mock.patch.dict('sys.modules', even_larger_program=nothing):
    from other_file import afunction


def this_test():
    assert afunction(2, 2) == 4

Upvotes: 1

bruno desthuilliers
bruno desthuilliers

Reputation: 77902

Quite simply: extract the functions that do not depend on large_program into another module and only test this module. Note that you can do this without breaking client code (code depending on your other_file module) by importing the relevant names in other_file:

# utils.py
import math

def afunction(x,y):
    return math.pow(x, y)

then

# other_file.py
import large_program

# this will allow client code to access `afunction` from `other_file`
from utils import afunction

def anotherfunc():
    return large_program()

and finally:

# test_file.py

# here we import from utils so we don't depend on `large_program`
from utils import afunction

def this_test():
    assert afunction(2, 2) == 4

Upvotes: 2

Related Questions