具有多个返回值的模拟/补丁 os.path.exists

Yep*_*_Me 4 python mocking python-2.7 python-unittest

我正在尝试测试我创建的一个函数,该函数遍历列表并调用列表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)
Run Code Online (Sandbox Code Playgroud)

使用第 1 行和第 2 行中的任何一个但不是同时使用 NameError: global name 'side_effect' is not defined

我发现了这个问题并像这样修改了我的代码:

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)
Run Code Online (Sandbox Code Playgroud)

这产生TypeError: 'module' object is not callable. 我也尝试切换这些行:

mockobj = mock(spec=os.path.exists)
mockobj.side_effect = side_effect
Run Code Online (Sandbox Code Playgroud)

为了这

mockobj = mock(spec=os.path)
mockobj.exists.side_effect = side_effect
Run Code Online (Sandbox Code Playgroud)

和这个

mockobj = mock(spec=os)
mockobj.path.exists.side_effect = side_effect
Run Code Online (Sandbox Code Playgroud)

产生相同的错误。谁能指出我做错了什么以及我能做些什么来让它发挥作用?

编辑: 在下面发布我的答案后,我意识到我的第一段代码实际上也可以工作,我只需要m.side_effect = TestClass.side_effect而不是m.side_effect = side_effect.

Yep*_*_Me 5

因此,经过更多的研究和反复试验,大部分示例都在这里: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)
Run Code Online (Sandbox Code Playgroud)

test电话os.path.exist中的每个项目arg_list,并返回所有项目的列表os.path.exist返回True的。这个测试现在通过了我想要的。