如何模拟 Python 系统属性,如 os.pathsep?

How to mock a Python system attribute like os.pathsep?

我正在尝试修改测试以同时处理 Linux 和 Windows。正在测试的代码使用os.pathsep。示例:

def path_split(pth):
    if os.pathsep in pth:
        return pth.split(os.pathsep)
    else:
        return [pth]

如果我 运行 使用冒号在 Linux 上进行以下测试,它会起作用:

class PathsepTest(TestCase):

    def test_path_split(self):
        result = path_split("foo:bar")
        assert result == ["foo", "bar"]

但是,如果我尝试将 os.pathsep 模拟为 return Windows 路径分隔符 (;)

class PathsepTest(TestCase):

    def test_path_split(self):
        windows_pathsep = ";"
        with patch.object(os, "pathsep", return_value=windows_pathsep):
            result = path_split("foo;bar")
            assert result == ["foo", "bar"]

它失败了

    def path_split(pth):
>       if os.pathsep in pth:
E       TypeError: 'in <string>' requires string as left operand, not MagicMock

为了更简单的功能

def get_pathsep():
    return os.pathsep

如果我这样做相应的测试失败

    def test_get_pathsep(self):
        windows_pathsep = ";"
        with patch.object(os, "pathsep", return_value=windows_pathsep):
            result = get_pathsep()
            assert result == windows_pathsep

但如果我这样做就通过了

            assert result.return_value == windows_pathsep

欢迎提出任何建议。

mock.patch 用另一个对象替换一个对象,默认是用 MagicMock.

替换

所以 patch.object(os, "pathsep", return_value=":"),将 os.pathsep 替换为 MagicMock。然后 return_value 指定调用模拟对象时的行为(即 os.pathsep.__call__

>>> with mock.patch("os.pathsep", return_value=";"):
...     print(os.pathsep())   # os.pathsep has been replaced by a callable
... 
;

但是 os.pathsep 不是可调用对象,它是 str。根据 documentation,您可以使用 new 参数简单地用另一个对象替换原始对象:

>>> with mock.patch("os.pathsep", new=";"):
...     print(os.pathsep)
... 
;