6

我需要修补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,并测试以查看正常功能。

这是回溯

4

4 回答 4

9

您可以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()
于 2012-09-28T13:31:46.600 回答
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
于 2012-09-27T12:51:18.537 回答
0

您可以在测试方法或测试类上使用补丁作为装饰器。它使代码看起来非常干净。请注意,已修补的对象被传递到测试方法中。您可以在测试类级别做同样的事情,模拟对象将被传递到每个测试方法中。在这种情况下不需要使用 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)

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

于 2012-09-27T13:51:26.130 回答
0

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

ps:如果你想做更多“声明性”的方式来描述你想要修补的单元的副作用,我建议使用库http://mockstar.readthedocs.org/

于 2012-09-28T13:26:13.417 回答