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