web-dev-qa-db-ja.com

モックpython複数の戻り値を持つ関数

倍数の値を返す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からの戻り値に独自の値を与えたい。そのため、2番目の関数を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を使用します

9
myg

return_valueではなく、モックのside_effectを設定する必要があります。

インスタンス化するときにこれを行うことができます:

c.myExampleFunction = Mock(return_value=["myName", 100, 200])
11
Daniel Roseman

これを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)

これは、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()
4
idjaw