【问题标题】:How to mock os.walk in python with a temporary filesystem?如何使用临时文件系统在 python 中模拟 os.walk?
【发布时间】:2014-08-23 08:52:27
【问题描述】:

我正在尝试测试一些使用 os.walk 的代码。我想创建一个临时的内存文件系统,我可以用 os.walk 将返回的示例(空)文件和目录填充它。这应该为我节省了模拟 os.walk 调用以模拟递归的复杂性。

具体来说,我要测试的代码是:

if recursive:
    log.debug("Recursively searching for files under %s" % path)

    for (dir_path, dirs, files) in os.walk(path):
        log.debug("Found %d files in %s: %s" % (len(files), path, files))
        for f in [os.path.join(dir_path, f) for f in files
                  if not re.search(exclude, f)]:
            yield f
else:
    log.debug("Non-recursively searching for files under %s" % path)

    for (dir_path, dirs, files) in os.walk(path):
        log.debug("Found %d files in %s: %s" % (len(files), path, files))
        for f in [os.path.join(dir_path, f) for f in files
                    if not re.search(exclude, f)]:
            yield f

这在 python 中可能吗?

【问题讨论】:

  • 你想只模拟返回的列表,还是模拟完整的文件功能?
  • 仅返回列表。

标签: python unit-testing testing mocking python-mock


【解决方案1】:

没有。在os.path.islink()os.path.isdir() 的协助下,os.walk() 完全围绕os.listdir() 构建。这些本质上是系统调用,因此您必须在系统级别模拟您的文件系统。除非你想写一个FUSE plugin,否则这不容易模拟。

所有os.walk() 需要返回的是一个元组列表,真的。除非您正在测试操纵 dirs 组件,否则它再简单不过了:

with mock.patch('os.walk') as mockwalk:
    mockwalk.return_value = [
        ('/foo', ('bar',), ('baz',)),
        ('/foo/bar', (), ('spam', 'eggs')),
    ]

这将模拟以下目录结构:

/foo
 ├── baz
 └── bar 
     ├── spam
     └── eggs

【讨论】:

  • 我认为这会更困难。谢谢
  • 谢谢!我将我的解决方案写得更简洁一些,但这也对我的解决方案有所帮助。记住“os.walk() 需要返回一个元组列表”。我的解决方案:@patch('test_module.os.walk') def test_walk(self, os_walk): os.walk.return_value[('/foo', ('',), ('file.txt',))]
  • 我认为那里缺少=os.walk.return_value 不可索引。 :-)
  • 实际上(), ('spam', 'eggs') 可能是[], ['spam', 'eggs']。并不是说你的不能在这里工作,但更接近真实的也没有什么坏处。
  • @naxa:实际上会,因为如果您更改被测代码以特别操作dir 组件,则测试需要更新。如果您要使用列表,您很容易忘记这一点。 :-)
猜你喜欢
  • 1970-01-01
  • 2023-04-10
  • 2013-11-09
  • 2013-02-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-05
相关资源
最近更新 更多