如何在导入时忽略某些 Python 模块?

How to ignore certain Python modules on import?

我正在尝试使用 Pytest 对我的一些代码执行单元测试。测试 运行 在 Docker 上的单独 Conda 环境中进行。我想测试我的代码的某些功能,但无法安装我的代码的所有模块,因为其中一些模块的安装很复杂,而且 运行.

需要花费时间

如何只从一个文件中导入某些模块,而不需要安装其他模块?

如果我尝试 运行 进行测试,同时从文件导入模块,我的测试会失败,因为它无法导入其他模块。

下面是我的文件系统的模型:

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()

如果我运行 Pytest,我会得到:

 E   ImportError: No module named 'large_program'

很简单:将不依赖large_program的函数提取到另一个模块中,只测试这个模块。请注意,通过在 other_file:

中导入相关名称,您可以在不破坏客户端代码(代码取决于您的 other_file 模块)的情况下执行此操作
# utils.py
import math

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

然后

# 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()

最后:

# 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

我喜欢 cristid9 的 mocking 想法,并将其与 dano 的 post here 相结合。我创建了一个名为“nothing.py”的空文件,它将用单元测试模拟替换“large_program”: 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

other_file.py看起来还是这个样子

import math
import large_program

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

def anotherfunc():
    return large_program()

您还可以在多个模块上应用 with 语句:

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