【问题标题】:How to mock python build in methods如何模拟python内置方法
【发布时间】:2012-05-30 16:40:15
【问题描述】:

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

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

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

那么在我的 unitest 中模拟构建 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 
}

【问题讨论】:

    标签: python unit-testing python-mock


    【解决方案1】:

    使用 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

    【讨论】:

    • 谢谢:) MagicMock 是否为您提供范围?比如模拟开始和停止。
    • 看看我回答中的链接。 :)
    【解决方案2】:

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

    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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-27
      • 2015-08-23
      • 1970-01-01
      • 1970-01-01
      • 2015-12-18
      • 2011-02-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多