【问题标题】:Mocking Directory Structure in Python在 Python 中模拟目录结构
【发布时间】:2014-10-17 20:49:41
【问题描述】:

下面有一些代码,用于输入文件、打开和处理,然后输出一些数据。我已经使功能正常工作,现在正在对其进行单元测试,下面是代码示例。

def foo(dir):
    path_to_search = join(dir, "/baz/foo")

   if isdir(path_to_search): 
   #path exists so do stuff...

        for fname in listdir(path_to_search):
            do_stuff()

   else:
       print "path doesn't exist"

我已经能够创建一个过去不容易存在的测试,但正如您在上面看到的,我断言目录结构的“/baz/foo”部分存在(在生产中目录结构必须有这个文件,在某些情况下它不会,我们也不需要处理它。)

我尝试使用 TempDir 创建一个临时目录结构并加入,但代码总是显示路径不存在。

是否可以模拟 os.listdir 的输出,这样我就不需要创建一个遵循所需 /baz/foo 约定的临时目录结构?

【问题讨论】:

  • 您可以为此使用 Labix Mocker 和 mocker.replace()
  • @LukasGraf:最好使用 stdlib unittest.mock 或者它的后向端口 mock
  • @MartijnPieters 我个人更喜欢 Labix Mocker,主要是因为它们似乎是唯一正确修补的。见Where to Patch。 Labix 模拟程序通过实际收集对其修补的对象的引用来为您解决这个问题,并修补和重置这些对象,它就可以正常工作。
  • @LukasGraf:我实际上不喜欢这种魔法。我想控制修补了哪些代码,而不是让它神奇地应用它无处不在
  • @MartijnPieters 在实际代码中,绝对是。在测试中,我欢迎任何让我的生活更轻松的事情。至于控制:如果像将import a; a.SomeName 更改为from a import SomeName 这样的简单重构可以以微妙的方式破坏您的测试,那也是失控。

标签: python unit-testing


【解决方案1】:

您不需要创建虚假的目录结构,只需模拟 isdir()listdir() 函数即可。

使用unittest.mock library(或外部mock library,这对于Python 版本

try:
    # Python >= 3.3 
    from unittest import mock
except ImportError:
    # Python < 3.3
    import mock

with mock.patch('yourmodule.isdir') as mocked_isdir, \
        mock.patch('yourmodule.listdir') as mocked_listdir:
    mocked_isdir.return_value = True
    mocked_listdir.return_value = ['filename1', 'filename2']

    yourmodule.foo('/spam/eggs')

    mocked_isdir.assert_called_with('/spam/eggs/baz/foo')
    mocked_listdir.assert_called_with('/spam/eggs/baz/foo')

【讨论】:

  • 嗯,你能再解释一下吗,当我给它“垃圾邮件/鸡蛋”作为输入时,它似乎不起作用。我看到我们在说 isdir 应该返回 true,并且 list dir 应该返回这些文件名,现在这些文件名是“真实的”还是我需要临时创建它们以便可以读取它们?
  • @openingceremony:您的代码不需要它们是真实的,因为任何需要真实路径的函数都已被您的模拟替换。它们不需要真正的路径,您只需将它们配置为返回您的被测代码期望看到的任何内容。
  • 我明白了,当我运行这段代码时,断言失败了,因为它们没有被调用,我的代码不应该调用 isdir/listdir 吗?
  • @openingceremony:确保你修补了正确的对象!见Where to patch。如果没有调用您的模拟,则说明您没有修补正确的对象。
  • 我仔细检查过,您似乎是对的,我将完整路径放入对象进行修补,我认为问题可能是因为我尝试运行的函数没有 listdir 作为一个属性?它从 os 导入它,不确定在这种情况下协议是什么,我尝试模拟 os.listdir ,但这似乎也不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 2013-11-03
  • 1970-01-01
  • 2014-02-18
  • 1970-01-01
相关资源
最近更新 更多