266

私は pythons mock.patch を使用しており、呼び出しごとに戻り値を変更したいと考えています。注意点は次のとおりです。パッチを適用する関数には入力がないため、入力に基づいて戻り値を変更することはできません。

参照用の私のコードは次のとおりです。

def get_boolean_response():
    response = io.prompt('y/n').lower()
    while response not in ('y', 'n', 'yes', 'no'):
        io.echo('Not a valid input. Try again'])
        response = io.prompt('y/n').lower()

    return response in ('y', 'yes')

私のテストコード:

@mock.patch('io')
def test_get_boolean_response(self, mock_io):
    #setup
    mock_io.prompt.return_value = ['x','y']
    result = operations.get_boolean_response()

    #test
    self.assertTrue(result)
    self.assertEqual(mock_io.prompt.call_count, 2)

io.prompt「入力」のプラットフォームに依存しない (python 2 および 3) バージョンです。したがって、最終的には、ユーザーの入力をモックアウトしようとしています。戻り値にリストを使用しようとしましたが、うまくいきません。

戻り値が無効な場合、ここで無限ループが発生することがわかります。したがって、テストが実際に終了するように、最終的に戻り値を変更する方法が必要です。

(この質問に答える別の方法は、単体テストでユーザー入力を模倣する方法を説明することです)


主に入力を変更する能力がないため、この質問の重複ではありません。

この質問に対する回答のコメントの 1 つは同じ行に沿っていますが、回答/コメントは提供されていません。

4

3 に答える 3

448

iterableをに割り当てることができside_effect、モックは呼び出されるたびにシーケンス内の次の値を返します。

>>> from unittest.mock import Mock
>>> m = Mock()
>>> m.side_effect = ['foo', 'bar', 'baz']
>>> m()
'foo'
>>> m()
'bar'
>>> m()
'baz'

Mock()ドキュメントの引用:

side_effectが iterable の場合、モックを呼び出すたびに iterable から次の値が返されます。

于 2014-07-22T20:34:16.490 に答える
-5

複数の戻り値に patch を使用することもできます。

@patch('Function_to_be_patched', return_value=['a', 'b', 'c'])

メソッドに複数のパッチを使用している場合、その順序は次のようになることに注意してください。

@patch('a')
@patch('b')
def test(mock_b, mock_a);
    pass

ここでわかるように、元に戻されます。最初に言及されたパッチは最後の位置になります。

于 2021-03-29T09:58:51.433 に答える