Python 测试:模拟 ImportError
Python testing: Simulate ImportError
我有以下代码
try:
from foo_fast import bar
except ImportError
from foo import bar
def some_function(a, b):
return bar(a, b)
我现在想测试 foo_fast
可以导入和不能导入的两种情况。
使用pytest和pytest-mock,我自然想把这两种情况封装在一个pytest fixture中,所以我想我会用
@pytest.fixture(params=(True, False))
def use_fast(request, mock):
if not request.param:
mock.patch("foo_fast.bar", side_effect=ImportError)
return request.param
def test_foo(use_fast):
assert some_function(1, 2)
然而,在测试开始之前导入语句似乎只有 运行 一次,所以我无法模拟 ImportError
.
如何模拟这些 ImportError
个案例?
您可以使用monkeypatch.setitem()
设置sys.modules['foo_fast'] = None
@pytest.fixture(params=(True, False))
def use_fast(request, monkeypatch):
if not request.param:
monkeypatch.setitem(sys.modules, 'foo_fast', None)
return request.param
def test_foo(use_fast):
assert some_function(1, 2)
请注意,在 Python 2
import foo_fast
然后会上升一个 ImportError
,而在 Python 3 中它会上升一个 ModuleNotFoundError
(它是 ImportError
的子类,所以 try...catch
块可以保持不变)
mock 库是可能的:
def test_import_error(self):
with mock.patch.dict('sys.modules', {'foo_fast.bar': None}):
# your tests with foo.bar
在这种情况下 from foo_fast import bar
将加注 ImportError
。
我有以下代码
try:
from foo_fast import bar
except ImportError
from foo import bar
def some_function(a, b):
return bar(a, b)
我现在想测试 foo_fast
可以导入和不能导入的两种情况。
使用pytest和pytest-mock,我自然想把这两种情况封装在一个pytest fixture中,所以我想我会用
@pytest.fixture(params=(True, False))
def use_fast(request, mock):
if not request.param:
mock.patch("foo_fast.bar", side_effect=ImportError)
return request.param
def test_foo(use_fast):
assert some_function(1, 2)
然而,在测试开始之前导入语句似乎只有 运行 一次,所以我无法模拟 ImportError
.
如何模拟这些 ImportError
个案例?
您可以使用monkeypatch.setitem()
设置sys.modules['foo_fast'] = None
@pytest.fixture(params=(True, False))
def use_fast(request, monkeypatch):
if not request.param:
monkeypatch.setitem(sys.modules, 'foo_fast', None)
return request.param
def test_foo(use_fast):
assert some_function(1, 2)
请注意,在 Python 2
import foo_fast
然后会上升一个 ImportError
,而在 Python 3 中它会上升一个 ModuleNotFoundError
(它是 ImportError
的子类,所以 try...catch
块可以保持不变)
mock 库是可能的:
def test_import_error(self):
with mock.patch.dict('sys.modules', {'foo_fast.bar': None}):
# your tests with foo.bar
在这种情况下 from foo_fast import bar
将加注 ImportError
。