Python测试:模拟ImportError

时间:2015-02-05 14:42:09

标签: python import mocking pytest

我有以下代码

try:
    from foo_fast import bar
except ImportError
    from foo import bar


def some_function(a, b):
    return foo(a, b)

我现在想测试可以导入foo_fast的两种情况以及无法导入的情况。

使用pytest和pytest-mock,我自然希望将这两种情况封装在pytest fixture中,所以我想我会用

@pytest.fixture(params=(True, False))
def use_fast(request, mock):

    if request.param is not True:
        mock.patch("foo_fast.bar", side_effect=ImportError)

    return request.param


def test_foo(use_fast):
    assert some_function(1, 2)

然而,似乎import语句只在测试开始之前运行一次,因此我无法模拟ImportError

如何模拟这些ImportError个案件?

2 个答案:

答案 0 :(得分:3)

可以使用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

答案 1 :(得分:0)

我已将代码更改为

try:
    import foo_fast as foo
except ImportError
    import foo


def some_function(a, b):
    return foo.bar(a, b)

现在可以测试它了。

@pytest.fixture(params=(True, False))
def use_fast(request, monkeypatch):
    if request.param:
        import foo
        import foo_fast
        monkeypatch.setattr(foo_fast, 'bar', foo.bar)
    return request.param


def test_foo(use_fast):
    assert some_function(1, 2)

这不会测试try ... except ImportError但我认为无论如何都不可能。

请注意

from foo import bar

不能以这种方式monkeypatched,所以我不得不稍微更改import语句。