通过环境设置测试模块变量

时间:2019-03-15 17:51:04

标签: python mocking pytest

让我们说我们喜欢一个foo模块,该模块根据环境设置变量,如下所示:

def get_foo():
    global FOO
    return FOO


def set_foo(val):
    global FOO
    FOO = val


def init_foo():
    import os
    if 'FOO' in os.environ:
        return os.environ['FOO']
    else:
        return 'foo'

try:
    FOO
except NameError:
    FOO = init_foo()
finally:
    print('module foo sets FOO: ', FOO)

我们如何进行测试以删除模块变量FOO并重新加载模块以进行正确设置?

from foo import get_foo
import pytest
import os
import importlib


def test_default():
    assert get_foo() == 'foo'

@pytest.mark.parametrize('value', ['foo', 'bar', 'baz'])
def test_foo_env_setup(value, monkeypatch):
    monkeypatch.setenv('FOO', value)
    assert 'FOO' in os.environ
    assert os.environ['FOO']
    import foo
    importlib.reload(foo)
    assert foo.get_foo() == value

我是否需要通过mocker设置上下文管理器?

1 个答案:

答案 0 :(得分:1)

该模块可以视为对象,因此可以在测试中删除FOO属性并执行importlib.reload

@pytest.fixture
def foo_mocker():
    import foo
    assert foo.FOO == 'foo'
    del foo.FOO
    yield
    foo.FOO = 'foo'


@pytest.mark.parametrize('value', ['foo', 'bar', 'baz'])
def test_foo_env_setup(value, monkeypatch, foo_mocker):
    monkeypatch.setenv('FOO', value)
    assert 'FOO' in os.environ
    assert os.environ['FOO']
    import foo
    importlib.reload(foo)
    assert foo.get_foo() == value