如何在Python中模拟ImportError当一个包被导入时

3
我有一个包,其中包含可选的库安装。当未安装该可选库并调用特定方法时,会引发一个自定义异常,提示未启用该功能需安装可选包。当可选库存在时,该方法才能被使用。
我希望使用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是否被引发。我希望这样做是为了覆盖率的原因。

2个回答

1

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

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

这意味着两件事情:
  1. 我可以单独测试 try_import 函数。

  2. 我可以简单地修补名称,如 mock.patch('__main__.derp', None)


0
你可以模拟 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')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接