是否可以在 Python 测试中模拟模块不可用?
Is it possible to simulate the unavailability of modules in Python tests?
我编写了一个 Python 程序,该程序利用 Unix 系统上的 resource
模块来执行一些计时操作,但回退到使用 time
模块 Windows(因为 resource
模块不可用)。代码看起来像这样:
try:
import resource
except ImportError:
import time
def fn():
# Implementation using the time module
else:
def fn():
# Implementation using the resource module
但是,我的测试目前只在 else
块中执行函数,因为 resource
模块在 Linux 上始终可用。有没有办法模拟内置模块的不可用性,以便我也可以测试基于 time
的函数?我查看了 mock
文档,但找不到任何关于此的具体信息。
有点乱,但您可以创建一个目录,其中包含一个名为 resource.py
的文件,该文件引发 ImportError
,并将该目录的路径添加到 sys.path
.
如果你想混合模拟测试和非模拟测试,你还必须在你想重试导入它时从 sys.modules
中删除模块,否则 sys.path
的更改不会有任何影响。如果有的话,子模块可能还有其他问题。
概念验证:
mocked_modules/resource.py
:
raise ImportError()
测试代码:
import sys
import os
original_path = sys.path[:]
def reset():
# Teardown
sys.path = original_path[:]
if "resource" in sys.modules:
del sys.modules["resource"]
import resource
print("resource exists")
reset()
sys.path.insert(0, os.path.join(os.getcwd(), "mocked_modules"))
try:
import resource
except ImportError:
print("resource does not exist")
reset()
import resource
print("resource exists")
输出:
resource exists
resource does not exist
resource exists
鉴于它有很多警告(参见 this question),这让我感到有点不安,所以如果是您的代码执行导入,您可能更愿意将导入抽象为一个函数并模拟它反而。或者或另外,您可以公开 "Implementation using the time module" 并直接测试它。
我编写了一个 Python 程序,该程序利用 Unix 系统上的 resource
模块来执行一些计时操作,但回退到使用 time
模块 Windows(因为 resource
模块不可用)。代码看起来像这样:
try:
import resource
except ImportError:
import time
def fn():
# Implementation using the time module
else:
def fn():
# Implementation using the resource module
但是,我的测试目前只在 else
块中执行函数,因为 resource
模块在 Linux 上始终可用。有没有办法模拟内置模块的不可用性,以便我也可以测试基于 time
的函数?我查看了 mock
文档,但找不到任何关于此的具体信息。
有点乱,但您可以创建一个目录,其中包含一个名为 resource.py
的文件,该文件引发 ImportError
,并将该目录的路径添加到 sys.path
.
如果你想混合模拟测试和非模拟测试,你还必须在你想重试导入它时从 sys.modules
中删除模块,否则 sys.path
的更改不会有任何影响。如果有的话,子模块可能还有其他问题。
概念验证:
mocked_modules/resource.py
:
raise ImportError()
测试代码:
import sys
import os
original_path = sys.path[:]
def reset():
# Teardown
sys.path = original_path[:]
if "resource" in sys.modules:
del sys.modules["resource"]
import resource
print("resource exists")
reset()
sys.path.insert(0, os.path.join(os.getcwd(), "mocked_modules"))
try:
import resource
except ImportError:
print("resource does not exist")
reset()
import resource
print("resource exists")
输出:
resource exists
resource does not exist
resource exists
鉴于它有很多警告(参见 this question),这让我感到有点不安,所以如果是您的代码执行导入,您可能更愿意将导入抽象为一个函数并模拟它反而。或者或另外,您可以公开 "Implementation using the time module" 并直接测试它。