仅为一个模块修补Mock的功能?

时间:2012-09-27 12:09:30

标签: python unit-testing python-mock

我需要修补os.listdir和其他os函数来测试我的Python函数。但是当它们被修补时,import语句失败了。是否可以仅在单个模块中修补此功能,真实的,并让tests.py正常工作?

以下是打破import

的示例
import os
from mock import patch

# when both isdir and isfile are patched
# the function crashes
@patch('os.path.isdir', return_value=False)
@patch('os.path.isfile', return_value=False)
def test(*args):
    import ipdb; ipdb.set_trace()
    real_function(some_arguments)
    pass

test()

我希望real_function看到修补后的os.path,并进行测试以查看正常功能。

here's the traceback

4 个答案:

答案 0 :(得分:5)

您可以使用patch作为上下文管理器,因此它只适用于with语句中的代码:

import os
from mock import patch

def test(*args):
    import ipdb; ipdb.set_trace()
    with patch('os.path.isdir', return_value=False):
        with patch('os.path.isfile', return_value=False):
            real_function(some_arguments)
    pass

test()

答案 1 :(得分:0)

以下适合您的需要。注意我在测试运行之前和之后打印os.listdir只是为了显示所有内容都返回到它的正确状态。

import unittest, os
from unittest import TestLoader, TextTestRunner

def tested_func(path):
    return os.listdir(path * 2)

class Example(unittest.TestCase):

    def setUp(self):
        self._listdir = os.listdir
        os.listdir = lambda p: ['a', 'b', 'a', 'b']

    def test_tested_func(self):
        self.assertEqual(tested_func('some_path'), ['a', 'b', 'a', 'b'])

    def tearDown(self):
        os.listdir = self._listdir

print os.listdir
TextTestRunner().run(TestLoader().loadTestsFromTestCase(Example))
print os.listdir

答案 2 :(得分:0)

您可以在测试方法或测试类中使用patch作为装饰器。它使代码非常干净。请注意,已修补的对象将传递给测试方法。您可以在测试类级别执行相同的操作,并将模拟对象传递到每个测试方法中。在这种情况下不需要使用setUp或tearDown,因为这都是自动处理的。

# module.py
import os

def tested_func(path):
    return os.listdir(path * 2)


# test.py
from mock import patch

@patch('module.os.listdir')
def test_tested_func(self, mock_listdir):
    mock_listdir.return_value = ['a', 'b']

    self.assertEqual(tested_func('some_path'), ['a', 'b', 'a', 'b'])
    mock_listdir.assert_called_with('some_path' * 2)

另请注意,您要在要实际测试的模块中模拟要修补的功能。

答案 3 :(得分:0)

你不仅“可以”,而且“你应该”做那个http://mock.readthedocs.org/en/latest/patch.html#where-to-patch

p.s。:如果你想用更多的“声明”方式来描述你要补丁的单位的side_effects,我推荐使用库http://mockstar.readthedocs.org/