PythonMox:如何仅为某些路径伪造os.path.exists()?
如何仅对某些路径模拟PythonMox:如何仅为某些路径伪造os.path.exists()?,python,mocking,partial,stub,mox,Python,Mocking,Partial,Stub,Mox,如何仅对某些路径模拟exists(),而对任何其他路径进行模拟 例如,被测试的类将调用exists(),并将在提供给它的路径上失败,因为这些路径在运行测试的系统上不存在 使用Mox可以完全删除exists(),但这会导致测试失败,因为与被测类无关的调用不会以实际方式执行 我想当调用exists()时,我可以使用with sideeffects()调用我自己的函数,将调用分为两个方向,但是我如何访问原始的exists() 这就是我到目前为止所做的: def test_with_os_path_ex
exists()
,而对任何其他路径进行模拟
例如,被测试的类将调用exists()
,并将在提供给它的路径上失败,因为这些路径在运行测试的系统上不存在
使用Mox可以完全删除exists()
,但这会导致测试失败,因为与被测类无关的调用不会以实际方式执行
我想当调用exists()
时,我可以使用with sideeffects()
调用我自己的函数,将调用分为两个方向,但是我如何访问原始的exists()
这就是我到目前为止所做的:
def test_with_os_path_exists_partially_mocked(self):
self.mox.StubOutWithMock(os.path, 'exists')
def exists(path):
if not re.match("^/test-path.*$", path):
return call_original_exists_somehow(path)
else:
# /test-path should always exist
return True
os.path.exists(mox.Regex("^.*$")).MultipleTimes().WithSideEffects(exists)
self.mox.ReplayAll()
under_test.run()
self.mox.VerifyAll()
Mox内部使用“存根”进行实际存根:
Mox.__init__()
self._mock_objects = []
self.stubs = stubout.StubOutForTesting()
Mox.StubOutWithMock()
...
self.stubs.Set(obj, attr_name, stub)
Stubout将存根保存在内部集合中:
StubOutForTesting.Set():
...
self.cache.append((parent, old_child, child_name))
由于中间调用的返回值缓存在模拟方法对象中,因此必须在副作用回调中重置
创建方法mock时,它将被推送到存储在\u expected\u calls\u queue
中。在重播模式下,预期的调用由MultipleTimeGroup
实例重复,该实例将跟踪对\u methods
中引用的每个方法的调用
因此,可以通过导航Mox.stubs.cache
来参考原始方法
此示例将模拟exists()
传递对原始函数的调用,如果调用不是以/test path
开头,则任何其他调用将始终返回True
class SomeTest(unittest.TestCase):
def setUp(self):
self.mox = mox.Mox()
def tearDown(self):
self.mox.UnsetStubs()
def test_with_os_path_exists_partially_mocked(self):
self.mox.StubOutWithMock(os.path, 'exists')
# local reference to Mox
mox_ = self.mox
# fake callback
def exists(path):
# reset returnvalues of previous calls
# iterate mocked methods. the indices denote
# the mocked object and method and should
# have the correct values
for method in mox_._mock_objects[0]._expected_calls_queue[0]._methods:
method._return_value = None
if not re.match("^/test-path.*$", path):
# call real exists() for all paths not
# starting with /test-path
# lookup original method:
# - filter by name only (simplest matching)
# - take the 2nd value in the tupel (the function)
orig_exists = filter(lambda x: x[2] == "exists", mox_.stubs.cache)[0][1]
# call it
return orig_exists(path)
else:
# hardcoded True for paths starting with /test-path
return True
# expect call with any argument, multiple times, and call above fake
os.path.exists(mox.Regex("^.*$")).MultipleTimes().WithSideEffects(exists)
self.mox.ReplayAll()
# test goes here
self.mox.VerifyAll()