模拟具有多个返回值的python函数

jaql4c8m  于 2023-04-19  发布在  Python
关注(0)|答案(3)|浏览(112)

我有一个返回多个值的python函数。我的函数:

def myExampleFunction(a,b)
    # here is my code
    return name, number1, number2

def FunctionIWantToTest(self):
    # here is my code
    myName, myNumber1, myNumber2 = self.myExampleFunction(a,b)

我想给FunctionIWantToTest的返回值给予我自己的值。所以,我试图用nosetest测试第二个函数,但我不知道如何模拟myExampleFunction的返回。
我试过这个:

def test_mytest(self):
    [...]
    c.myExampleFunction = Mock()
    c.myExampleFunction.side_effect = ["myName", 100, 200]
    [...]

但它不起作用。当我启动nosetests时,我读到这样的消息:

ValueError: too many values to unpack

我用的是python 2.7.3

pjngdqdw

pjngdqdw1#

您需要设置模拟的return_value,而不是side_effect
您可以在示例化它时执行以下操作:

c.myExampleFunction = Mock(return_value=["myName", 100, 200])
dgenwo3n

dgenwo3n2#

我只是想分享如何让它与side_effect一起工作。我整理了一个简化的版本来展示如何在您的用例中使用side_effect
side_effect的行为与return_value不同,当你为side_effect提供一个包含条目的列表时,你实际上是在说,每次调用你的模拟方法时,它都会返回列表中的每个条目作为其返回值。这实际上就是为什么你会得到 ValueError:要解包的值太多(应为3),因为这样做:

[1, 2, 3]

你是说,每次调用我的模拟方法,返回1,然后下一次调用该方法时,返回2,然后返回3。
考虑到这一点,如果你设置你的side_effect,像这样:

[('stuff1', 'stuff2', 'stuff3')]

你现在说的是,当你调用side_effect时,列表中的第一项是将返回的内容。实际上是:

('stuff1', 'stuff2', 'stuff3')

或者,您可以执行以下操作:

my_test_foo.side_effect = lambda x, y: (1, 2, 3)

它通过接受两个参数并返回它应该返回的三个值来模拟您正在测试的方法。
因此,考虑到这一点,您的测试可以构建为:

import unittest
from unittest.mock import Mock

from mock import patch
from stuff import FunctionIWantToTest

class MyTest(unittest.TestCase):

    @patch('stuff.myExampleFunction', return_value=Mock())
    def test_mytest(self, m_example_function):
        m_example_function.side_effect = [("stuff1", 100, 200)]
        # m_example_function.side_effect = lambda x, y: ("stuff1", 100, 200)

        a, b, c = FunctionIWantToTest()

if __name__ == '__main__':
    unittest.main()
w8rqjzmb

w8rqjzmb3#

可以用更简单的方法来做,比如:

@patch('path.to.the.function')
def test_bla(self, mock_func):
    mock_func.return_value = 'return 1', 'return 2', 'return 3'
    ...

相关问题