我正在尝试测试我在列表中迭代的函数,并为列表中的每个项调用os.path.exists
。我的测试是将函数传递给2个对象的列表。我需要os.path.exists
为其中一个返回True
,为另一个返回False
。我试过这个:
import mock
import os
import unittest
class TestClass(unittest.TestCase):
values = {1 : True, 2 : False}
def side_effect(arg):
return values[arg]
def testFunction(self):
with mock.patch('os.path.exists') as m:
m.return_value = side_effect # 1
m.side_effect = side_effect # 2
arglist = [1, 2]
ret = test(argList)
使用第1行和第2行中的任何一行而不是两者都给出NameError: global name 'side_effect' is not defined
我发现了这个question并修改了我的代码:
import mock
import os
class TestClass(unittest.TestCase):
values = {1 : True, 2 : False}
def side_effect(arg):
return values[arg]
def testFunction(self):
mockobj = mock(spec=os.path.exists)
mockobj.side_effect = side_effect
arglist = [1, 2]
ret = test(argList)
这会产生TypeError: 'module' object is not callable
。
我也试过切换这些行:
mockobj = mock(spec=os.path.exists)
mockobj.side_effect = side_effect
这个
mockobj = mock(spec=os.path)
mockobj.exists.side_effect = side_effect
和这个
mockobj = mock(spec=os)
mockobj.path.exists.side_effect = side_effect
产生相同的错误。任何人都可以指出我做错了什么以及我能做些什么才能让它发挥作用?
修改
在下面发布我的答案后,我意识到我的第一段代码实际上也有效,我只需要m.side_effect = TestClass.side_effect
而不是m.side_effect = side_effect
。
答案 0 :(得分:4)
所以经过一些研究和反复试验,大部分示例都在这里:http://www.voidspace.org.uk/python/mock/patch.html,我解决了我的问题。
import mock
import os
def side_effect(arg):
if arg == 1:
return True
else:
return False
class TestClass(unittest.TestCase):
patcher = mock.patch('os.path.exists')
mock_thing = patcher.start()
mock_thing.side_effect = side_effect
arg_list = [1, 2]
ret = test(arg_list)
self.assertItemsEqual([1], ret)
test
为os.path.exist
中的每个项目调用arg_list
,并返回os.path.exist
返回True
的所有项目的列表。这个测试现在通过我想要的方式。
答案 1 :(得分:0)
你可以做到self.side_effect
我相信。由于初始定义不是全局定义,因此调用side_effect
查看全局范围