9

オブジェクトが呼び出されるunittest.mock.Mockと、呼び出しの正確な署名で引数の値を確認できます。

from unittest.mock import Mock

m = Mock()  # creation of mock
m('foo', bar='baz')  # call to the mock
m.assert_called_once_with('foo', bar='baz')  # check call arguments

同じ値を持つ別の署名のチェックは失敗します。'baz'たとえば、名前付き引数の代わりに位置引数としてチェックすると、アサーションは失敗します。

m.assert_called_once_with('foo', 'baz')
# AssertionError: Expected call: mock('foo', 'baz')
# Actual call: mock('foo', bar='baz')

それはしなければなりません。置き換えられた関数m

def actual_fu(foo, bar):
    # do something

その場合、呼び出しは同等になりますが、

def a_different_actual_fu(foo, *args, bar='some default'):
    # do something

その場合、呼び出しは同等ではありません。Mockは実際の関数のシグネチャを知らないため、最初のケースでの等価性に依存できません。

モック (またはアサーション ヘルパー関数など) にモックによって置き換えられた実際の関数を知らせることによって、それらが位置的に渡されたのか、キーワード引数として渡されたのかにとらわれない呼び出し引数の値をチェックする方法はありますか?

オプションの引数またはautospeccingMockを使用して、置換するオブジェクト (関数またはメソッド) をオブジェクトに認識させることができますが、それらは別の目的 (モックで許可する呼び出しを制限する) を提供し、後で影響しません。 -事実確認。spec

4

1 に答える 1

7

Mock オブジェクトは、オプションの spec 引数または で置き換えるオブジェクト (関数またはメソッド) を認識することができますがautospeccing、それらは別の目的に役立ちます..

これはまさにIssue 17015: mock がよりスマートになり、仕様の署名の改善の問題が何であったかを調べます。spec実際には非常に関連しており、モックが関数シグネチャを認識できるようになりました。

モックがキーワード引数で呼び出されたとアサートすると、モックがどのように失敗するかを確認してください - 実際の関数シグネチャについて知らせずに:

>>> from unittest.mock import Mock
>>>
>>> def actual_fu(foo, bar):
...     pass
>>>
>>> m = Mock()
>>> m('foo', bar='baz')
<Mock name='mock()' id='4356741496'>
>>>
>>> m.assert_called_once_with(foo='foo', bar='baz')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/unittest/mock.py", line 803, in assert_called_once_with
    return self.assert_called_with(*args, **kwargs)
  File "/Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/unittest/mock.py", line 792, in assert_called_with
    raise AssertionError(_error_message()) from cause
AssertionError: Expected call: mock(bar='baz', foo='foo')
Actual call: mock('foo', bar='baz')

そして今、私たちが提供した場合にすべてがどのように通過するかを見てくださいspec:

>>> m = Mock(spec=actual_fu)
>>> m('foo', bar='baz')
<Mock name='mock()' id='4356249528'>
>>> 
>>> m.assert_called_once_with(foo='foo', bar='baz')
>>> m.assert_called_once_with('foo', bar='baz')
>>> m.assert_called_once_with(bar='baz', foo='foo')
>>> m.assert_called_once_with('foo', 'baz')
>>>

(Python 3.5.1 を使用)

于 2016-03-30T16:17:21.837 に答える