Python如何在导入包时模拟导入程序

Python如何在导入包时模拟导入程序,python,python-3.x,testing,mocking,Python,Python 3.x,Testing,Mocking,我有一个安装了可选库的软件包。当可选库不存在且调用特定方法时,将引发自定义异常,说明在未安装可选包的情况下无法启用该功能。如果存在可选库,则可以使用该方法 我想用pytest测试这两种情况 我正在导入库,如: try: import derp except ImportError: pass 然后在函数中,通过检查程序包是否位于sys.modules中来检查库是否已安装 def my_feature_method(): if 'derp' not in sys.modu

我有一个安装了可选库的软件包。当可选库不存在且调用特定方法时,将引发自定义异常,说明在未安装可选包的情况下无法启用该功能。如果存在可选库,则可以使用该方法

我想用pytest测试这两种情况

我正在导入库,如:

try:
    import derp
except ImportError:
    pass
然后在函数中,通过检查程序包是否位于
sys.modules
中来检查库是否已安装

def my_feature_method():
    if 'derp' not in sys.modules:
        raise Exception('this feature requires the derp package to be installed')

    # do some stuff ...
我希望能够测试在pytest中安装和未安装包的情况

编辑

目前我正在使用

with mock.patch.dict('sys.modules'):
    del sys.modules['derp']
    # run test

但这实际上并没有测试是否引发了
ImportError
。我之所以要这样做是因为覆盖率原因您可以模拟
sys.path
,以防止
import
在库中找到您的文件。差不多

import unittest.mock
import sys
with unittest.mock.patch('sys.path', []):
    try:
        import derp
    except ImportError:
        pass
    if 'derp' not in sys.modules:
        raise Exception('missing derp')

好吧,我通过稍微改变一下设置解决了这个问题:

def try_import(name, package=None):
    try:
        return importlib.import_module(name, package=package)
    except ImportError:
        pass

derp = try_import('derp')

if not globals()['derp']:
    raise Exception('this feature requires the derp package to be installed')
这意味着两件事:

  • 我可以单独测试
    try\u import
    功能

  • 我可以简单地修补名称,如
    mock.patch(“\uu main\uu.derp',None)