2

我有一个 python 方法执行以下操作:

  1. 使用 os.listdir(/test) 列出目录下的文件
  2. 正则表达式匹配目录下的一些文件,将文件放在一个列表中
  3. 从列表中的文件中读取内容,做一些聚合的东西。

显然,我要测试的唯一有趣的部分是 2、3,所以 1 绝对是我想要模拟的东西。我开始在 setUp() 和 tearDown() 的 /test 文件夹下创建/删除补丁文件。但是同事告诉我,在 unitest 中进行 I/O 并不是一个好主意。

那么在我的单元中模拟构建 os.listdir() 的最佳方法是什么?或者有什么选择?

我可以做些什么来实现以下目标:

setUp() {
    #mock a few files eg.test1.txt, test2.txt, test3.txt under directory /test 
    #without physically creating them using I/O
}
tearDown() {
   #whatever cleanup required 
}
4

2 回答 2

4

使用 Mock 模块怎么样?

>>> import os
>>> from mock import MagicMock
>>> os.listdir = MagicMock(return_value=['file1.txt', 'file2.txt', 'file3.txt'])
>>> os.listdir('./test')
['file1.txt', 'file2.txt', 'file3.txt']

如果您不想 mokey-patch(即中断)os,那么您可以使用 mock_os 或类似的东西。

阅读有关启动和停止的信息:http:
//docs.python.org/dev/py3k/library/unittest.mock.html#patch-methods-start-and-stop

并且:
http ://docs.python.org/dev/py3k/library/unittest.mock.html#quick-guide

于 2012-05-30T17:01:59.530 回答
4

我发现模拟模块是列出文件和读取模拟数据的方式。这些当然可以组合在一个测试中,但为了清楚起见,我已将它们分开在一个工作文件中。

import unittest
from mock import patch, mock_open
import os


class Test(unittest.TestCase):
    @patch.object(os, 'listdir')
    def test_listdir(self, mock_listdir):
        expected = ['file1.txt', 'file2.txt']
        mock_listdir.return_value = expected
        self.assertEquals(expected, Code().get_folder("~"))

    def test_file_mock(self):
        expected_string = "Some File Contents"
        mocked_file_object = mock_open(read_data=expected_string)
        with patch('__main__.open', mocked_file_object, create=True) as mocked_open:
            self.assertEquals(expected_string, Code().get_file_as_string('any'))


class Code(object):
    def get_folder(self, folder):
        return os.listdir(folder)

    def get_file_as_string(self, afile):
        with open(afile, 'r') as handle:
            return handle.read()


if __name__ == '__main__':
    unittest.main()
于 2015-01-08T15:08:21.363 回答