mock/patch os.path.exists具有多个返回值

2024-04-29 19:22:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试测试一个函数,该函数遍历一个列表,并为列表中的每个项调用os.path.exists。我的测试是向函数传递一个包含两个对象的列表。我需要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


Tags: path函数importtrue列表osdefexists
2条回答

所以,经过更多的研究和反复试验,我用这里的大多数例子: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)

testarg_list中的每个项调用os.path.exist,并返回os.path.exist为其返回True的所有项的列表。这个测试现在通过了我的要求。

我相信你本可以做到的。由于初始定义不是全局的,调用side_effect将在全局范围内进行

相关问题 更多 >