26.5. "unittest.mock" --- モックオブジェクトライブラリ
******************************************************

バージョン 3.3 で追加.

**ソースコード:** Lib/unittest/mock.py

======================================================================

"unittest.mock" はPython におけるソフトウェアテストのためのライブラリ
です。テスト中のシステムの一部をモックオブジェクトで置き換え、それらが
どのように使われるかをアサートすることができます。

"unittest.mock" はコア "Mock" クラスを提供しており、それによってテスト
スイート内でたくさんのスタブを作成しなくてすみます 。アクションの実行
後、メソッドや属性の使用や実引数についてアサートできます。また通常の方
法で戻り値を明記したり、必要な属性を設定することもできます。

加えて、 mock はテストのスコープ内にあるモジュールやクラスの属性を変更
する "patch()" デコレータを提供します。さらに、ユニークなオブジェクト
の作成には "sentinel" が利用できます。 "Mock" や "MagicMock" 、
"patch()" の利用例は quick guide を参照してください。

Mock はとても使いやすく、 "unittest" で利用するために設計されています
。Mock は多くのモックフレームワークで使われる 'record -> replay' パタ
ーンの代わりに、 'action -> assertion' パターンに基づいています。

以前の Python バージョン向けにバックポートされた "unittest.mock" があ
り、 mock on PyPI  として利用可能です。


26.5.1. クイックガイド
======================

"Mock" および "MagicMock" オブジェクトはアクセスしたすべての属性とメソ
ッドを作成し、どのように使用されたかについての詳細な情報を格納します。
戻り値を指定したり利用できる属性を制限するために "Mock" および
"MagicMock" を設定でき、どのよう使用されたかについてアサートできます:

>>> from unittest.mock import MagicMock
>>> thing = ProductionClass()
>>> thing.method = MagicMock(return_value=3)
>>> thing.method(3, 4, 5, key='value')
3
>>> thing.method.assert_called_with(3, 4, 5, key='value')

"side_effect" によって、モック呼び出し時の例外発生などの副作用を実行で
きます:

>>> mock = Mock(side_effect=KeyError('foo'))
>>> mock()
Traceback (most recent call last):
 ...
KeyError: 'foo'

>>> values = {'a': 1, 'b': 2, 'c': 3}
>>> def side_effect(arg):
...     return values[arg]
...
>>> mock.side_effect = side_effect
>>> mock('a'), mock('b'), mock('c')
(1, 2, 3)
>>> mock.side_effect = [5, 4, 3, 2, 1]
>>> mock(), mock(), mock()
(5, 4, 3)

モックには多くの設定法や挙動の制御法があります。例えば *spec* 引数によ
って別のオブジェクトからの仕様を受け取るよう設定できます。 spec にない
モックの属性やメソッドにアクセスを試みた場合、 "AttributeError" で失敗
します。

"patch()" デコレータ / コンテキストマネージャーによってテスト対象のモ
ジュール内のクラスやオブジェクトを簡単にモックできます。指定したオブジ
ェクトはテスト中はモック (または別のオブジェクト) に置換され、テスト終
了時に復元されます:

>>> from unittest.mock import patch
>>> @patch('module.ClassName2')
... @patch('module.ClassName1')
... def test(MockClass1, MockClass2):
...     module.ClassName1()
...     module.ClassName2()
...     assert MockClass1 is module.ClassName1
...     assert MockClass2 is module.ClassName2
...     assert MockClass1.called
...     assert MockClass2.called
...
>>> test()

注釈:

  patch デコレータをネストした場合、モックは適用されるときと同じ順番 (
  デコレータを適用するときの通常の *python* の順番) でデコレートされた
  関数に渡されます。 つまり下から順に適用されるため、上の例では
  "module.ClassName1" のモックが最初に渡されます。"patch()" では探索さ
  れる名前空間内のオブジェクトにパッチをあてることが重要です。通常は単
  純ですが、クイックガイドには where-to-patch を読んでください。

"patch()" デコレータと同様に with 文でコンテキストマネージャーとして使
用できます:

>>> with patch.object(ProductionClass, 'method', return_value=None) as mock_method:
...     thing = ProductionClass()
...     thing.method(1, 2, 3)
...
>>> mock_method.assert_called_once_with(1, 2, 3)

また、 "patch.dict()" を使うと、スコープ内だけで辞書に値を設定し、テス
ト終了時には元の状態に復元されます:

>>> foo = {'key': 'value'}
>>> original = foo.copy()
>>> with patch.dict(foo, {'newkey': 'newvalue'}, clear=True):
...     assert foo == {'newkey': 'newvalue'}
...
>>> assert foo == original

mock は Python の マジックメソッド のモックをサポートしています。 マジ
ックメソッドのもっとも簡単な利用法は "MagicMock" クラスと使うことです
。以下のように利用します:

>>> mock = MagicMock()
>>> mock.__str__.return_value = 'foobarbaz'
>>> str(mock)
'foobarbaz'
>>> mock.__str__.assert_called_with()

mock によってマジックメソッドに関数 (あるいは他の Mock インスタンス)
を割り当てることができ、それらは適切に呼び出されます。 "MagicMock" ク
ラスは、すべてのマジックメソッドがあらかじめ作成されている点を除けば
"Mock" クラスと一緒です (まあ、とにかく便利ってこと)。

以下は通常の Mock クラスでマジックメソッドを利用する例です:

>>> mock = Mock()
>>> mock.__str__ = Mock(return_value='wheeeeee')
>>> str(mock)
'wheeeeee'

テスト内のモックオブジェクトが置換するオブジェクトと同じ API を持つこ
とを保証するには、 auto-speccing を使うことができます。パッチをあてる
*autospec* 引数、または "create_autospec()" 関数を通じて auto-speccing
は行われます。 auto-speccing は置換するオブジェクトと同じ属性とメソッ
ドを持つモックオブジェクトを作成し、すべての関数および (コンストラクタ
を含む) メソッドは本物のオブジェクトと同じ呼び出しシグネチャを持ちます
。

誤って使用された場合、モックは製品コードと同じように失敗されることが保
証されています:

>>> from unittest.mock import create_autospec
>>> def function(a, b, c):
...     pass
...
>>> mock_function = create_autospec(function, return_value='fishy')
>>> mock_function(1, 2, 3)
'fishy'
>>> mock_function.assert_called_once_with(1, 2, 3)
>>> mock_function('wrong arguments')
Traceback (most recent call last):
 ...
TypeError: <lambda>() takes exactly 3 arguments (1 given)

"create_autospec()" はクラスにおいても利用でき、 "__init__" メソッドの
シグニチャをコピーします。また、呼び出し可能オブジェクトについても
"__call__"  メソッドのシグニチャをコピーします。


26.5.2. Mock クラス
===================

"Mock" は、コードにおけるスタブの使用やテストダブルを置き換えるための
柔軟なモックオブジェクトです。モックは呼び出し可能で、属性にアクセスし
た場合それを新たなモックとして作成します [1]。同じ属性にアクセスした場
合は常に同じモックを返します。 モックはどのように使われたかを記録する
ので、コードがモックに行うことについてアサートできます。

"MagicMock" は "Mock" のサブクラスで、すべてのマジックメソッドが事前に
作成され、利用できます。また、呼び出し不可能なモックを作成する場合には
、呼び出し不能な変種の "NonCallableMock" や "NonCallableMagicMock" が
あります。

"patch()" デコレータによって特定のモジュール内のクラスを "Mock" オブジ
ェクトで一時的に置換することが簡単にできます。デフォルトでは "patch()"
は "MagicMock" を作成します。 "patch()" に渡す *new_callable* 引数によ
って、別の "Mock" クラスを指定できます。

class unittest.mock.Mock(spec=None, side_effect=None, return_value=DEFAULT, wraps=None, name=None, spec_set=None, unsafe=False, **kwargs)

   新しい "Mock" オブジェクトを作成します。 "Mock" はモックオブジェク
   トの挙動を指定するオプション引数をいくつか取ります:

   * *spec*: モックオブジェクトの仕様として働く文字列のリストもしくは
     存在するオブジェクト (クラスもしくはインスタンス) を指定します。
     オブジェクトを渡した場合には、 dir 関数によって文字列のリストが生
     成されます (サポートされない特殊属性や特殊メソッドは除く) 。この
     リストにない属性にアクセスした際には  "AttributeError" が発生しま
     す。

     *spec* が (文字列のリストではなく) オブジェクトの場合、
     "__class__" はスペックオブジェクトのクラスを返します。これによっ
     てモックが "isinstance()" テストに通るようになります。

   * *spec_set*: より厳しい *spec* です。こちらを利用した場合、
     *spec_set* に渡されたオブジェクトに存在しない属性に対し *設定* や
     取得をしようとした際に "AttributeError" が発生します。

   * *side_effect*: モックが呼び出された際に呼び出される関数を指定しま
     す。 "side_effect" 属性を参考にしてください。例外を発生させたり、
     動的に戻り値を変更する場合に便利です。関数には、モックと同じ引数
     が渡され、 "DEFAULT" を返さない限りはこの関数の戻り値が使われます
     。

     一方で、 *side_effect* には、例外クラスやインスタンスを指定できま
     す。この場合は、モックが呼び出された際に指定された例外を発生しま
     す。

     もし、 *side_effect* にイテレート可能オブジェクトを指定した場合に
     は、モックの呼び出しごとに順に値を返します。

     *side_effect* に "None" を指定した場合には、設定がクリアされます
     。

   * *return_value*: モックが呼び出された際に返す値です。デフォルトで
     は (最初にアクセスされた際に生成される) 新しい Mock を返します。
     "return_value" を参照してください。

   * *unsafe*: デフォルトでは、何らかの属性が *assert* または *assret*
     で始まると "AttributeError" が上がります。 "unsafe=True" を渡すと
     、これらの属性へのアクセスが許可されます。

     バージョン 3.5 で追加.

   * *wraps*: ラップするモックオブジェクトを指定します。 もし *wraps*
     に "None" 以外を指定した場合には、モックの呼び出し時に指定したオ
     ブジェクトを呼び出します (戻り値は実際の結果を返します)。 属性へ
     のアクセスは、ラップされたオブジェクトと対応するモックを返します
     (すなわち、存在しない属性にアクセスしようとした場合は
     "AttributeError" が発生します)。

     *return_value* が設定されている場合には、ラップ対象は呼び出されず
     、 *return_value* が返されます。

   * *name*: もし、モックが *name* を持つ場合には、モックの repr とし
     て使われます。デバッグの際に役立つでしょう。この値は、子のモック
     にも伝播します。

   モックは、任意のキーワード引数を与えることができます。これらはモッ
   クの生成後、属性の設定に使われます。詳細は "configure_mock()" を参
   照してください。

   assert_called(*args, **kwargs)

      モックが少なくとも一度は呼び出されたことをアサートします。

      >>> mock = Mock()
      >>> mock.method()
      <Mock name='mock.method()' id='...'>
      >>> mock.method.assert_called()

      バージョン 3.6 で追加.

   assert_called_once(*args, **kwargs)

      モックが一度だけ呼び出されたことをアサートします。

      >>> mock = Mock()
      >>> mock.method()
      <Mock name='mock.method()' id='...'>
      >>> mock.method.assert_called_once()
      >>> mock.method()
      <Mock name='mock.method()' id='...'>
      >>> mock.method.assert_called_once()
      Traceback (most recent call last):
      ...
      AssertionError: Expected 'method' to have been called once. Called 2 times.

      バージョン 3.6 で追加.

   assert_called_with(*args, **kwargs)

      このメソッドは呼び出しが特定の方法で行われたことをアサートするの
      に便利な方法です:

      >>> mock = Mock()
      >>> mock.method(1, 2, 3, test='wow')
      <Mock name='mock.method()' id='...'>
      >>> mock.method.assert_called_with(1, 2, 3, test='wow')

   assert_called_once_with(*args, **kwargs)

      Assert that the mock was called exactly once and that that call
      was with the specified arguments.

      >>> mock = Mock(return_value=None)
      >>> mock('foo', bar='baz')
      >>> mock.assert_called_once_with('foo', bar='baz')
      >>> mock('other', bar='values')
      >>> mock.assert_called_once_with('other', bar='values')
      Traceback (most recent call last):
        ...
      AssertionError: Expected 'mock' to be called once. Called 2 times.

   assert_any_call(*args, **kwargs)

      モックが特定の引数で呼び出されたことがあるのをアサートします。

      The assert passes if the mock has *ever* been called, unlike
      "assert_called_with()" and "assert_called_once_with()" that only
      pass if the call is the most recent one, and in the case of
      "assert_called_once_with()" it must also be the only call.

      >>> mock = Mock(return_value=None)
      >>> mock(1, 2, arg='thing')
      >>> mock('some', 'thing', 'else')
      >>> mock.assert_any_call(1, 2, arg='thing')

   assert_has_calls(calls, any_order=False)

      モックが特定の呼び出しで呼ばれたことをアサートします。呼び出しで
      は "mock_calls" のリストがチェックされます。

      *any_order* が false の場合(デフォルト)、呼び出しは連続していな
      ければなりません。指定された呼び出しの前、あるいは呼び出しの後に
      余分な呼び出しがある場合があります。

      *any_order* が true の場合、呼び出しは任意の順番でも構いませんが
      、それらがすべて "mock_calls" に現われなければなりません。

      >>> mock = Mock(return_value=None)
      >>> mock(1)
      >>> mock(2)
      >>> mock(3)
      >>> mock(4)
      >>> calls = [call(2), call(3)]
      >>> mock.assert_has_calls(calls)
      >>> calls = [call(4), call(2), call(3)]
      >>> mock.assert_has_calls(calls, any_order=True)

   assert_not_called()

      モックが呼ばれないことをアサートします。

      >>> m = Mock()
      >>> m.hello.assert_not_called()
      >>> obj = m.hello()
      >>> m.hello.assert_not_called()
      Traceback (most recent call last):
        ...
      AssertionError: Expected 'hello' to not have been called. Called 1 times.

      バージョン 3.5 で追加.

   reset_mock(*, return_value=False, side_effect=False)

      モックオブジェクトのすべての呼び出し属性をリセットします:

      >>> mock = Mock(return_value=None)
      >>> mock('hello')
      >>> mock.called
      True
      >>> mock.reset_mock()
      >>> mock.called
      False

      バージョン 3.6 で変更: 2つのキーワード専用引数が reset_mock 関数
      に追加されました。

      This can be useful where you want to make a series of assertions
      that reuse the same object. Note that "reset_mock()" *doesn't*
      clear the return value, "side_effect" or any child attributes
      you have set using normal assignment by default. In case you
      want to reset *return_value* or "side_effect", then pass the
      corresponding parameter as "True". Child mocks and the return
      value mock (if any) are reset as well.

      注釈:

        *return_value*, and "side_effect" are keyword only argument.

   mock_add_spec(spec, spec_set=False)

      モックに仕様を追加します。 *spec* にはオブジェクトもしくは文字列
      のリストを指定してください。 *spec* で設定した属性は、モックの属
      性としてのみアクセスできます。

      *spec_set* が真なら、 spec 以外の属性は設定できません。

   attach_mock(mock, attribute)

      属性として mock を設定して、その名前と親を入れ替えます。設定され
      たモックの呼び出しは、 "method_calls" や "mock_calls" 属性に記録
      されます。

   configure_mock(**kwargs)

      モックの属性をキーワード引数で設定します。

      属性に加え、子の戻り値や副作用もドット表記を用いて設定でき、辞書
      はメソッドの呼び出し時にアンパックされます:

      >>> mock = Mock()
      >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
      >>> mock.configure_mock(**attrs)
      >>> mock.method()
      3
      >>> mock.other()
      Traceback (most recent call last):
        ...
      KeyError

      コンストラクタの呼び出しでも同様に行うことができます:

      >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
      >>> mock = Mock(some_attribute='eggs', **attrs)
      >>> mock.some_attribute
      'eggs'
      >>> mock.method()
      3
      >>> mock.other()
      Traceback (most recent call last):
        ...
      KeyError

      "configure_mock()" は、モック生成後のコンフィギュレーションを容
      易に行うために存在します。

   __dir__()

      "Mock" オブジェクトは、有用な結果を得るために "dir(some_mock)"
      の結果を制限します。 *spec* を設定したモックに対しては、許可され
      た属性のみを含みます。

      このフィルタが何をしていて、どのように停止させるかは、
      "FILTER_DIR" を参照してください。

   _get_child_mock(**kw)

      子のモックを作成し、その値を返すようにしてください。デフォルトで
      は親と同じタイプで作成されます。サブクラスで子モックの作成される
      方法をカスタマイズしたい場合には、このメソッドをオーバーライドし
      ます。

      呼び出し不可能なモックに対しては、(カスタムのサブクラスではなく)
      呼び出し可能なモックが使われます。

   called

      このモックが呼び出されたかどうかを表します:

      >>> mock = Mock(return_value=None)
      >>> mock.called
      False
      >>> mock()
      >>> mock.called
      True

   call_count

      このモックオブジェクトが呼び出された回数を返します:

      >>> mock = Mock(return_value=None)
      >>> mock.call_count
      0
      >>> mock()
      >>> mock()
      >>> mock.call_count
      2

   return_value

      モックが呼び出された際に返す値を設定します:

      >>> mock = Mock()
      >>> mock.return_value = 'fish'
      >>> mock()
      'fish'

      デフォルトの戻り値はモックオブジェクトです。通常の方法で設定する
      こともできます:

      >>> mock = Mock()
      >>> mock.return_value.attribute = sentinel.Attribute
      >>> mock.return_value()
      <Mock name='mock()()' id='...'>
      >>> mock.return_value.assert_called_with()

      "return_value" は生成時にも設定可能です:

      >>> mock = Mock(return_value=3)
      >>> mock.return_value
      3
      >>> mock()
      3

   side_effect

      このモックが呼ばれた際に呼び出される関数、イテラブル、もしくは発
      生させる例外 (クラスまたはインスタンス) を設定できます。

      関数を渡した場合はモックと同じ引数で呼び出され、 "DEFAULT" を返
      さない限りはその関数の戻り値が返されます。関数が "DEFAULT" を返
      した場合は ( "return_value" によって) モックの通常の値を返します
      。

      iterable が渡された場合、その値はイテレータを取り出すために使用
      されます。イテレータは毎回の呼び出しにおいて値を yield しなけれ
      ばなりません。この値は、送出される例外インスタンスか、呼び出しか
      らモックに返される値のいずれかです ("DEFAULT" の処理は関数の場合
      と同一です)。

      以下はモックが (API による例外の扱いをテストするために) 例外を発
      生させる例です:

      >>> mock = Mock()
      >>> mock.side_effect = Exception('Boom!')
      >>> mock()
      Traceback (most recent call last):
        ...
      Exception: Boom!

      "side_effect" を使用して連続的に値を返します:

      >>> mock = Mock()
      >>> mock.side_effect = [3, 2, 1]
      >>> mock(), mock(), mock()
      (3, 2, 1)

      呼び出し可能オブジェクトを使います:

      >>> mock = Mock(return_value=3)
      >>> def side_effect(*args, **kwargs):
      ...     return DEFAULT
      ...
      >>> mock.side_effect = side_effect
      >>> mock()
      3

      "side_effect" は生成時にも設定可能です。呼び出し時の値に 1 を加
      えて返す例を以下に示します:

      >>> side_effect = lambda value: value + 1
      >>> mock = Mock(side_effect=side_effect)
      >>> mock(3)
      4
      >>> mock(-8)
      -7

      "side_effect" に "None" を設定した場合はクリアされます:

      >>> m = Mock(side_effect=KeyError, return_value=3)
      >>> m()
      Traceback (most recent call last):
       ...
      KeyError
      >>> m.side_effect = None
      >>> m()
      3

   call_args

      (もし呼び出されたことがなければ) "None"、それ以外であれば最後に
      呼び出された時の引数を返します。引数はタプルの形式で表されます:
      最初の要素はモックが呼び出された際の順序付きの引数 (もしくは空の
      タプル) 、二つ目の要素はキーワード引数 (もしくは空の辞書) です。

      >>> mock = Mock(return_value=None)
      >>> print(mock.call_args)
      None
      >>> mock()
      >>> mock.call_args
      call()
      >>> mock.call_args == ()
      True
      >>> mock(3, 4)
      >>> mock.call_args
      call(3, 4)
      >>> mock.call_args == ((3, 4),)
      True
      >>> mock(3, 4, 5, key='fish', next='w00t!')
      >>> mock.call_args
      call(3, 4, 5, key='fish', next='w00t!')

      "call_args" は、 "call_args_list" や "method_calls" 、
      "mock_calls" と同様、 "call" オブジェクトです。これらはタプルと
      してアンパックすることで個別に取り出すことができます。そして、よ
      り複雑なアサーションを行うことができます。 calls as tuples を参
      照してください。

   call_args_list

      モックの呼び出しを順に記録したリストです (よって、このリストの長
      さはモックが呼び出された回数と等しくなります)。モックを作成して
      から一度も呼び出しを行なっていない場合は、空のリストが返されます
      。 "call" オブジェクトは、 "call_args_list" の比較対象となる呼び
      出しのリストを作成する際に便利です。

      >>> mock = Mock(return_value=None)
      >>> mock()
      >>> mock(3, 4)
      >>> mock(key='fish', next='w00t!')
      >>> mock.call_args_list
      [call(), call(3, 4), call(key='fish', next='w00t!')]
      >>> expected = [(), ((3, 4),), ({'key': 'fish', 'next': 'w00t!'},)]
      >>> mock.call_args_list == expected
      True

      "call_args_list" のメンバは "call" オブジェクトです。タプルとし
      てアンパックすることで個別に取り出すことができます。 calls as
      tuples を参照してください。

   method_calls

      自身の呼び出しと同様に、モックはメソッドや属性、そして *それらの
      * メソッドや属性の呼び出しも追跡します:

      >>> mock = Mock()
      >>> mock.method()
      <Mock name='mock.method()' id='...'>
      >>> mock.property.method.attribute()
      <Mock name='mock.property.method.attribute()' id='...'>
      >>> mock.method_calls
      [call.method(), call.property.method.attribute()]

      "method_calls" のメンバは "call" オブジェクトです。タプルとして
      アンパックすることで個別に取り出すことができます。 calls as
      tuples を参照してください。

   mock_calls

      "mock_calls" は、メソッド、特殊メソッド、 *そして* 戻り値のモッ
      クまで、モックオブジェクトに対する *すべての* 呼び出しを記録しま
      す。

      >>> mock = MagicMock()
      >>> result = mock(1, 2, 3)
      >>> mock.first(a=3)
      <MagicMock name='mock.first()' id='...'>
      >>> mock.second()
      <MagicMock name='mock.second()' id='...'>
      >>> int(mock)
      1
      >>> result(1)
      <MagicMock name='mock()()' id='...'>
      >>> expected = [call(1, 2, 3), call.first(a=3), call.second(),
      ... call.__int__(), call()(1)]
      >>> mock.mock_calls == expected
      True

      "mock_calls" のメンバは "call" オブジェクトです。タプルとしてア
      ンパックすることで個別に取り出すことができます。 calls as tuples
      を参照してください。

      注釈:

        The way "mock_calls" are recorded means that where nested
        calls are made, the parameters of ancestor calls are not
        recorded and so will always compare equal:

        >>> mock = MagicMock()
        >>> mock.top(a=3).bottom()
        <MagicMock name='mock.top().bottom()' id='...'>
        >>> mock.mock_calls
        [call.top(a=3), call.top().bottom()]
        >>> mock.mock_calls[-1] == call.top(a=-1).bottom()
        True

   __class__

      通常、オブジェクトの "__class__" 属性はその型を返します。 "spec"
      を設定したオブジェクトの場合、 "__class__" は代わりに "spec" の
      クラスを返します。これにより、置き換え / 偽装しているオブジェク
      トに対する "isinstance()" も通過することができます:

      >>> mock = Mock(spec=3)
      >>> isinstance(mock, int)
      True

      "__class__" は書き換え可能で、 "isinstance()" を通るために必ず
      spec を使う必要はありません:

      >>> mock = Mock()
      >>> mock.__class__ = dict
      >>> isinstance(mock, dict)
      True

class unittest.mock.NonCallableMock(spec=None, wraps=None, name=None, spec_set=None, **kwargs)

   呼び出しができない "Mock" です。コンストラクタのパラメータは "Mock"
   と同様ですが、 *return_value* や *side_effect* は意味を持ちません。

"spec" か "spec_set" にクラスかインスタンスを渡した mock は
"isinstance()" テストをパスします:

>>> mock = Mock(spec=SomeClass)
>>> isinstance(mock, SomeClass)
True
>>> mock = Mock(spec_set=SomeClass())
>>> isinstance(mock, SomeClass)
True

"Mock" クラスは、 特殊メソッドをサポートしています。すべての詳細は
magic methods を参照してください。

モッククラスや "patch()" デコレータは、任意のキーワード引数を設定でき
ます。 "patch()" デコレータへのキーワード引数は、モックが作られる際の
コンストラクタに渡されます。キーワード引数は、モックの属性を設定します
:

>>> m = MagicMock(attribute=3, other='fish')
>>> m.attribute
3
>>> m.other
'fish'

子の戻り値や副作用も、ドットで表記することで同様に設定できます。呼び出
し時に直接ドットのついた名前を使用できないので、作成した辞書を "**" で
アンパックする必要があります:

>>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
>>> mock = Mock(some_attribute='eggs', **attrs)
>>> mock.some_attribute
'eggs'
>>> mock.method()
3
>>> mock.other()
Traceback (most recent call last):
  ...
KeyError

*spec* (または *spec_set*) によって作成された呼び出し可能なモックは、
モックへの呼び出しがマッチしたときに仕様オブジェクトのシグネチャを内省
します。したがって、引数を位置引数として渡したか名前で渡したかどうかに
関わらず、実際の呼び出しの引数とマッチすることができます:

   >>> def f(a, b, c): pass
   ...
   >>> mock = Mock(spec=f)
   >>> mock(1, 2, c=3)
   <Mock name='mock()' id='140161580456576'>
   >>> mock.assert_called_with(1, 2, 3)
   >>> mock.assert_called_with(a=1, b=2, c=3)

これは "assert_called_with()", "assert_called_once_with()",
"assert_has_calls()" and "assert_any_call()" にも適用されます。
autospec を使う と、 モックオブジェクトのメソッド呼び出しにも適用され
ます。

   バージョン 3.4 で変更: spec や autospec を用いて生成されたモックオ
   ブジェクトは、シグネチャを考慮するようになりました。

class unittest.mock.PropertyMock(*args, **kwargs)

   プロパティもしくはディスクリプタとして使われるためのモックです。
   "PropertyMock" は、 "__get__()" と "__set__()" メソッドを提供し、戻
   り値を指定することができます。

   オブジェクトから "PropertyMock" のインスタンスを取得することは、引
   数を与えないモックの呼び出しに相当します。設定は、 設定する値を伴っ
   た呼び出しになります。

   >>> class Foo:
   ...     @property
   ...     def foo(self):
   ...         return 'something'
   ...     @foo.setter
   ...     def foo(self, value):
   ...         pass
   ...
   >>> with patch('__main__.Foo.foo', new_callable=PropertyMock) as mock_foo:
   ...     mock_foo.return_value = 'mockity-mock'
   ...     this_foo = Foo()
   ...     print(this_foo.foo)
   ...     this_foo.foo = 6
   ...
   mockity-mock
   >>> mock_foo.mock_calls
   [call(), call(6)]

"PropertyMock" を直接モックに取り付ける方法は、モックの属性を保存する
方法によりうまく動作しません。代わりに、モック型に取り付けてください:

   >>> m = MagicMock()
   >>> p = PropertyMock(return_value=3)
   >>> type(m).foo = p
   >>> m.foo
   3
   >>> p.assert_called_once_with()


26.5.2.1. 呼び出し
------------------

モックオブジェクトは呼び出し可能です。呼び出しの戻り値は
"return_value" 属性に設定された値です。デフォルトでは新しいモックオブ
ジェクトを返します。この新しいモックは、属性に最初にアクセスした際に作
成されます (明示もしくはモックの呼び出しによって)。 そしてそれは保存さ
れ、それ以降は同じものが返されます。

呼び出しはオブジェクトとして "call_args" や "call_args_list" に記録さ
れます。

もし "side_effect" が設定されている場合は、その呼び出しが記録された後
に呼び出されます。よって、もし "side_effect" が例外を発生させても、そ
の呼び出しは記録されます。

呼び出された際に例外を発生させるモックを作成するためには、
"side_effect" を例外クラスかインスタンスにする方法が最もシンプルです:

>>> m = MagicMock(side_effect=IndexError)
>>> m(1, 2, 3)
Traceback (most recent call last):
  ...
IndexError
>>> m.mock_calls
[call(1, 2, 3)]
>>> m.side_effect = KeyError('Bang!')
>>> m('two', 'three', 'four')
Traceback (most recent call last):
  ...
KeyError: 'Bang!'
>>> m.mock_calls
[call(1, 2, 3), call('two', 'three', 'four')]

もし "side_effect" が関数だった場合には、その関数の戻り値がモックを呼
び出した際の戻り値になります。 "side_effect" 関数には、モックの呼び出
し時に与えられた引数と同じ物があたえられます。これにより、入力によって
動的に値を返すことができます:

>>> def side_effect(value):
...     return value + 1
...
>>> m = MagicMock(side_effect=side_effect)
>>> m(1)
2
>>> m(2)
3
>>> m.mock_calls
[call(1), call(2)]

もし、モックにデフォルトの戻り値 (新しいモック)  や設定した値を返して
欲しい場合は、2つの方法があります。 "side_effect" の内部で
"mock.return_value" を返すか "DEFAULT" を返します:

>>> m = MagicMock()
>>> def side_effect(*args, **kwargs):
...     return m.return_value
...
>>> m.side_effect = side_effect
>>> m.return_value = 3
>>> m()
3
>>> def side_effect(*args, **kwargs):
...     return DEFAULT
...
>>> m.side_effect = side_effect
>>> m()
3

"side_effect" を削除し、デフォルトの挙動を行うようにするには、
"side_effect" に "None" を設定します:

>>> m = MagicMock(return_value=6)
>>> def side_effect(*args, **kwargs):
...     return 3
...
>>> m.side_effect = side_effect
>>> m()
3
>>> m.side_effect = None
>>> m()
6

"side_effect" には、イテレート可能オブジェクトを設定できます。モックが
呼び出されるごとに、イテレート可能オブジェクトから戻り値を得ます (イテ
レート可能オブジェクトが尽きて "StopIteration" が発生するまで):

>>> m = MagicMock(side_effect=[1, 2, 3])
>>> m()
1
>>> m()
2
>>> m()
3
>>> m()
Traceback (most recent call last):
  ...
StopIteration

もしイテレート可能オブジェクトの要素が例外だった場合には、戻り値として
返される代わりに例外が発生します:

   >>> iterable = (33, ValueError, 66)
   >>> m = MagicMock(side_effect=iterable)
   >>> m()
   33
   >>> m()
   Traceback (most recent call last):
    ...
   ValueError
   >>> m()
   66


26.5.2.2. 属性の削除
--------------------

モックオブジェクトは要求に応じて属性を生成することで，任意のオブジェク
トとして振る舞うことができます。

"hasattr()" の呼び出しの際に "False" を返したり，属性にアクセスした際
に "AttributeError" を発生させたりしたい場合， "spec" を用いる方法があ
ります．しかし，この方法は必ずしも便利ではありません．

属性を削除することで， "AttributeError" を発生させ，アクセスを "妨げる
" ようになります．

>>> mock = MagicMock()
>>> hasattr(mock, 'm')
True
>>> del mock.m
>>> hasattr(mock, 'm')
False
>>> del mock.f
>>> mock.f
Traceback (most recent call last):
    ...
AttributeError: f


26.5.2.3. Mock の名前と name 属性
---------------------------------

"name" は "Mock" コンストラクタの引数なので、モックオブジェクトが
"name" 属性を持つことを望む場合、単に生成時にそれを渡すことはできませ
ん。2つの選択肢があります。1つのオプションは "configure_mock()" を使用
することです:

   >>> mock = MagicMock()
   >>> mock.configure_mock(name='my_name')
   >>> mock.name
   'my_name'

より単純なオプションはモックの生成後に単に "name" 属性をセットすること
です:

   >>> mock = MagicMock()
   >>> mock.name = "foo"


26.5.2.4. 属性として設定されるモック
------------------------------------

属性 (もしくは戻り値) に他のモックを設定した場合、このモックは "子" に
なります。この子に対する呼び出しは、親の "method_calls" や
"mock_calls" に記録されます。これは、子のモックを構成し、親にそのモッ
クを設定する際に有用です。また、親に対して設定したすべての子の呼び出し
を記録するため、それらの間の順番を確認する際にも有用です:

>>> parent = MagicMock()
>>> child1 = MagicMock(return_value=None)
>>> child2 = MagicMock(return_value=None)
>>> parent.child1 = child1
>>> parent.child2 = child2
>>> child1(1)
>>> child2(2)
>>> parent.mock_calls
[call.child1(1), call.child2(2)]

モックが名前をもつ場合は、例外的に扱われます。何らかの理由で "子守り"
が発生してほしくないときに、それを防ぐことができます。

>>> mock = MagicMock()
>>> not_a_child = MagicMock(name='not-a-child')
>>> mock.attribute = not_a_child
>>> mock.attribute()
<MagicMock name='not-a-child()' id='...'>
>>> mock.mock_calls
[]

"patch()" を用いて作成したモックには、自動的に名前が与えられます。名前
を持つモックを設定したい場合には、親に対して "attach_mock()" メソッド
を呼び出します:

>>> thing1 = object()
>>> thing2 = object()
>>> parent = MagicMock()
>>> with patch('__main__.thing1', return_value=None) as child1:
...     with patch('__main__.thing2', return_value=None) as child2:
...         parent.attach_mock(child1, 'child1')
...         parent.attach_mock(child2, 'child2')
...         child1('one')
...         child2('two')
...
>>> parent.mock_calls
[call.child1('one'), call.child2('two')]

[1] 例外は特殊メソッドと属性だけです (これらは2つのアンダースコアで開
    始・終了します)。モックはこれらの代わりに "AttributeError" を発生
    させます。これは、インタープリタが暗黙的にこれらのメソッドを要求す
    るためであり、特殊メソッドを予測する際に *非常に* 混乱してしまいま
    す。もし特殊メソッドのサポートが必要な場合は、 magic methods を参
    照してください。


26.5.3. patcher
===============

patch デコレータは、その関数のスコープ内でパッチを適用するオブジェクト
に対して使用されます。たとえ例外が発生したとしても、パッチは自動的に解
除されます。これらすべての機能は文やクラスのデコレータとしても使用でき
ます。


26.5.3.1. patch
---------------

注釈:

  "patch()" を使うのは簡単です。重要なのは正しい名前空間に対して patch
  することです。 where to patch セクションを参照してください。

unittest.mock.patch(target, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)

   "patch()" は関数デコレータ、クラスデコレータ、コンテキストマネージ
   ャーとして利用できます。関数や with 文の body では、 *target* は
   *new* オブジェクトにパッチされます。関数/with 文が終了すると、パッ
   チは元に戻されます。

   *new* が省略された場合、 target は "MagicMock" に置き換えられます。
   "patch()" がデコレータとして利用され、 *new* が省略された場合、生成
   された mock はデコレータの対象となる関数の追加の引数として渡されま
   す。 "patch()" がコンテキストマネージャーとして利用された場合、コン
   テキストマネージャーが生成した mock を返します。

   *target* は "'package.module.ClassName'" の形式の文字列でなければな
   りません。 *target* はインポートされ、指定されたオブジェクトが
   *new* オブジェクトに置き換えられます。なので、 *target* は
   "patch()" を呼び出した環境からインポート可能でなければなりません。
   target がインポートされるのは、デコレートした時ではなく、デコレート
   された関数が呼び出された時です。

   patch が "MagicMock" を生成する場合、 *spec* と *spec_set* キーワー
   ド引数は "MagicMock" に渡されます。

   加えて、 "spec=True" もしくは "spec_set=True" を渡すことで、モック
   対象のオブジェクトが spec/spec_set に渡されます。

   *new_callable* を使って、 *new* オブジェクトを生成するために呼び出
   されるクラスや callable オブジェクトを指定することができます。デフ
   ォルトでは "MagicMock" が使われます。

   より強力な *spec* の形は *autospec* です。 "autospec=True" を指定し
   た場合、 mock は置換対象となるオブジェクトから得られる spec で生成
   されます。 mock のすべての属性もまた置換対象となるオブジェクトの属
   性に応じた spec を持ちます。 mock されたメソッドや関数は引数をチェ
   ックし、間違ったシグネチャで呼び出された場合は "TypeError" を発生さ
   せます。クラスを置き換える mock の場合、その戻り値 (つまりインスタ
   ンス) はそのクラスと同じ spec を持ちます。 "create_autospec()" 関数
   と autospec を使う を参照してください。

   置換対象ではなく任意のオブジェクトを spec として使うために、
   "autospec=True" の代わりに、 "autospec=some_object" と指定すること
   ができます。

   デフォルトでは、 "patch()" は存在しない属性を置換しません。
   "create=True" を渡してかつ属性が存在しなければ、パッチを当てた関数
   が呼ばれる時に patch は属性を作成し、それを後で再び削除します。これ
   は、プロダクションコードがランタイムに作成する属性に対してテストを
   書くのに役立ちます。これは危険な場合があるため、デフォルトではオフ
   になっています。それをオンにすると、実際には存在しないような API に
   対して通るテストを書くことができてしまいます!

   注釈:

     バージョン 3.5 で変更: モジュールのビルトインにパッチを当てようと
     しているなら、 "create=True" を渡す必要はありません。それはデフォ
     ルトで追加されます。

   patch は "TestCase" のクラスデコレータとして利用できます。この場合
   そのクラスの各テストメソッドをデコレートします。これによりテストメ
   ソッドが同じ patch を共有している場合に退屈なコードを減らすことがで
   きます。 "patch()" は "patch.TEST_PREFIX" で始まるメソッド名のメソ
   ッドを探します。デフォルトではこれは "'test'" で、 "unittest" がテ
   ストを探す方法とマッチしています。 "patch.TEST_PREFIX" を設定するこ
   とで異なる prefix を指定することもできます。

   patch は with 文を使ってコンテキストマネージャーとして使うこともで
   きます。その場合パッチは with 文のブロック内でのみ適用されます。
   "as" を使って、 "as" に続いて指定した変数にパッチされたオブジェクト
   が代入されます。これは "patch()" が mock オブジェクトを生成するとき
   に便利です。

   "patch()" は任意のキーワード引数を受け取り、それを "Mock" (あるいは
   *new_callable*) の生成時に渡します。

   異なるユースケースのために、 "patch.dict(...)",
   "patch.multiple(...)", "patch.object(...)" が用意されています。

"patch()" を関数デコレータとして利用し、 mock を生成してそれをデコレー
トされた関数に渡します:

>>> @patch('__main__.SomeClass')
... def function(normal_argument, mock_class):
...     print(mock_class is SomeClass)
...
>>> function(None)
True

クラスをパッチするとそのクラスを "MagicMock" の **インスタンス** に置
き換えます。テスト中のコードからそのクラスがインスタンス化される場合、
mock の "return_value" が利用されます。

クラスが複数回インスタンス化される場合、 "side_effect" を利用して毎回
新しい mock を返すようにできます。もしくは、 *return_value* に、何でも
好きなものを設定できます。

パッチしたクラスの *インスタンス* のメソッドの戻り値をカスタマイズした
い場合、 "return_value" に対して設定しなければなりません。例:

>>> class Class:
...     def method(self):
...         pass
...
>>> with patch('__main__.Class') as MockClass:
...     instance = MockClass.return_value
...     instance.method.return_value = 'foo'
...     assert Class() is instance
...     assert Class().method() == 'foo'
...

*spec* か *spec_set* を指定し、 "patch()" が *クラス* を置換するとき、
生成された mock の戻り値は同じ spec を持ちます。

>>> Original = Class
>>> patcher = patch('__main__.Class', spec=True)
>>> MockClass = patcher.start()
>>> instance = MockClass()
>>> assert isinstance(instance, Original)
>>> patcher.stop()

*new_callable* 引数は、デフォルトの "MagicMock" の代わりに別のクラスを
モックとして生成したい場合に便利です。例えば、 "NonCallableMock" を利
用したい場合:

>>> thing = object()
>>> with patch('__main__.thing', new_callable=NonCallableMock) as mock_thing:
...     assert thing is mock_thing
...     thing()
...
Traceback (most recent call last):
  ...
TypeError: 'NonCallableMock' object is not callable

別のユースケースとしては、オブジェクトを "io.StringIO" インスタンスで
置き換えることがあります:

>>> from io import StringIO
>>> def foo():
...     print('Something')
...
>>> @patch('sys.stdout', new_callable=StringIO)
... def test(mock_stdout):
...     foo()
...     assert mock_stdout.getvalue() == 'Something\n'
...
>>> test()

"patch()" に mock を生成させる場合、たいてい最初に必要なことはその
mock をセットアップすることです。幾らかのセットアップは patch の呼び出
しから行うことができます。任意のキーワード引数が、生成された mock の属
性に設定されます。

>>> patcher = patch('__main__.thing', first='one', second='two')
>>> mock_thing = patcher.start()
>>> mock_thing.first
'one'
>>> mock_thing.second
'two'

生成された mock の属性のさらに属性、 "return_value" "side_effect" など
もセットアップできます。これらはキーワード引数のシンタックスでは直接指
定できませんが、それらをキーとする辞書を "**" を使って "patch()" に渡
すことができます。

>>> config = {'method.return_value': 3, 'other.side_effect': KeyError}
>>> patcher = patch('__main__.thing', **config)
>>> mock_thing = patcher.start()
>>> mock_thing.method()
3
>>> mock_thing.other()
Traceback (most recent call last):
  ...
KeyError


26.5.3.2. patch.object
----------------------

patch.object(target, attribute, new=DEFAULT, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)

   オブジェクト (*target*) の指定された名前のメンバー (*attribute*) を
   mock オブジェクトでパッチします。

   "patch.object()" はデコレータ、クラスデコレータ、コンテキストマネー
   ジャーとして利用できます。引数の *new*, *spec*, *create*,
   *spec_set*, *autospec*, *new_callable* は "patch()" と同じ意味を持
   ちます。 "patch()" と同じく、 "patch.object()" も mock を生成するた
   めの任意のキーワード引数を受け取ります。

   クラスデコレータとして利用する場合、 "patch.object()" は
   "patch.TEST_PREFIX" にしたがってラップするメソッドを選択します。

"patch.object()" の呼び出しには3引数の形式と2引数の形式があります。 3
引数の場合、 patch 対象のオブジェクト、属性名、その属性を置き換えるオ
ブジェクトを取ります。

2引数の形式では、置き換えるオブジェクトを省略し、生成された mock がデ
コレート対象となる関数に追加の引数として渡されます:

>>> @patch.object(SomeClass, 'class_method')
... def test(mock_method):
...     SomeClass.class_method(3)
...     mock_method.assert_called_with(3)
...
>>> test()

*spec*, *create* やその他の "patch.object()" の引数は "patch()" の引数
と同じ意味を持ちます。


26.5.3.3. patch.dict
--------------------

patch.dict(in_dict, values=(), clear=False, **kwargs)

   辞書や辞書のようなオブジェクトにパッチし、テスト後に元の状態に戻し
   ます。

   *in_dict* は辞書やその他のマップ型のコンテナです。マップ型の場合、
   最低限 get, set, del 操作とキーに対するイテレートをサポートしている
   必要があります。

   *in_dict* に辞書を指定する文字列を渡した場合、それをインポートして
   取得します。

   *values* は対象の辞書にセットする値を含む、辞書か "(key, value)" ペ
   アの iterable です。

   *clear* が true なら、新しい値が設定される前に辞書がクリアされます
   。

   "patch.dict()" はまた、任意のキーワード引数を受け取って辞書に設定し
   ます。

   "patch.dict()" はコンテキストマネージャー、デコレータ、クラスデコレ
   ータとして利用できます。クラスデコレータとして利用する場合、
   "patch.dict()" は "patch.TEST_PREFIX" にしたがってラップするメソッ
   ドを選択します。

"patch.dict()" を使うと、辞書にメンバーを追加するか、または単にテスト
が辞書を変更して、その後テストが終了した時にその辞書が確実に復元される
ようにすることができます。

>>> foo = {}
>>> with patch.dict(foo, {'newkey': 'newvalue'}):
...     assert foo == {'newkey': 'newvalue'}
...
>>> assert foo == {}

>>> import os
>>> with patch.dict('os.environ', {'newkey': 'newvalue'}):
...     print(os.environ['newkey'])
...
newvalue
>>> assert 'newkey' not in os.environ

"patch.dict()" を呼び出すときにキーワード引数を使って辞書に値をセット
することができます。

>>> mymodule = MagicMock()
>>> mymodule.function.return_value = 'fish'
>>> with patch.dict('sys.modules', mymodule=mymodule):
...     import mymodule
...     mymodule.function('some', 'args')
...
'fish'

"patch.dict()" は辞書ではなくても辞書ライクなオブジェクトに対して使う
ことができます。対象となるオブジェクトは最低限、 get, set, del そして
イテレーションかメンバーのテストのどちらかをサポートする必要があります
。これはマジックメソッドの  "__getitem__()", "__setitem__()",
"__delitem__()" そして "__iter__()" か "__contains__()" のどちらかに対
応します。

>>> class Container:
...     def __init__(self):
...         self.values = {}
...     def __getitem__(self, name):
...         return self.values[name]
...     def __setitem__(self, name, value):
...         self.values[name] = value
...     def __delitem__(self, name):
...         del self.values[name]
...     def __iter__(self):
...         return iter(self.values)
...
>>> thing = Container()
>>> thing['one'] = 1
>>> with patch.dict(thing, one=2, two=3):
...     assert thing['one'] == 2
...     assert thing['two'] == 3
...
>>> assert thing['one'] == 1
>>> assert list(thing) == ['one']


26.5.3.4. patch.multiple
------------------------

patch.multiple(target, spec=None, create=False, spec_set=None, autospec=None, new_callable=None, **kwargs)

   1回の呼び出しで複数のパッチを実行します。パッチ対象のオブジェクト (
   あるいはそのオブジェクトをインポートするための文字列) と、パッチ用
   のキーワード引数を取ります:

      with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'):
          ...

   "patch.multiple()" に mock を生成させたい場合、キーワード引数の値に
   "DEFAULT" を指定します。この場合生成されたモックはデコレート対象の
   関数にキーワード引数として渡され、コンテキストマネージャーとして利
   用された場合は辞書として返します。

   "patch.multiple()" はデコレータ、クラスデコレータ、コンテキストマネ
   ージャーとして使えます。引数の *spec*, *spec_set*, *create*,
   *autospec*, *new_callable* は "patch()" の引数と同じ意味を持ちます
   。これらの引数は "patch.multiple()" によって適用される *すべての*
   パッチに対して適用されます。

   クラスデコレータとして利用する場合、 "patch.multiple()" は
   "patch.TEST_PREFIX" にしたがってラップするメソッドを選択します。

"patch.multiple()" に mock を生成させたい場合、キーワード引数の値に
"DEFAULT" を指定します。この場合生成されたモックはデコレート対象の関数
にキーワード引数として渡されます。

>>> thing = object()
>>> other = object()

>>> @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
... def test_function(thing, other):
...     assert isinstance(thing, MagicMock)
...     assert isinstance(other, MagicMock)
...
>>> test_function()

"patch.multiple()" は他の "patch" デコレータとネストして利用できますが
、キーワード引数は "patch()" によって作られる通常の引数の *後ろ* で受
け取る必要があります。

>>> @patch('sys.exit')
... @patch.multiple('__main__', thing=DEFAULT, other=DEFAULT)
... def test_function(mock_exit, other, thing):
...     assert 'other' in repr(other)
...     assert 'thing' in repr(thing)
...     assert 'exit' in repr(mock_exit)
...
>>> test_function()

"patch.multiple()" がコンテキストマネージャーとして利用される場合、コ
ンテキストマネージャーが返す値は、名前がキーで値が生成された mock とな
る辞書です。

>>> with patch.multiple('__main__', thing=DEFAULT, other=DEFAULT) as values:
...     assert 'other' in repr(values['other'])
...     assert 'thing' in repr(values['thing'])
...     assert values['thing'] is thing
...     assert values['other'] is other
...


26.5.3.5. patch のメソッド: start と stop
-----------------------------------------

すべての patcher は "start()" と "stop()" メソッドを持ちます。これを使
うと、 with 文やデコレータをネストさせずに、 "setUp" メソッドで複数の
パッチをシンプルに適用させることができます。

これらのメソッドを使うには、 "patch()", *patch.object*, "patch.dict()"
を通常の関数のように呼び出して、戻り値の "patcher" オブジェクトを保持
します。その "start()" メソッドでパッチを適用し、 "stop()" メソッドで
巻き戻すことができます。

"patch()" に mock を生成させる場合、 "patcher.start" の呼び出しの戻り
値として mock を受け取れます。

>>> patcher = patch('package.module.ClassName')
>>> from package import module
>>> original = module.ClassName
>>> new_mock = patcher.start()
>>> assert module.ClassName is not original
>>> assert module.ClassName is new_mock
>>> patcher.stop()
>>> assert module.ClassName is original
>>> assert module.ClassName is not new_mock

この方式の典型的なユースケースは、 "TestCase" の "setUp" メソッドで複
数のパッチを行うことです:

>>> class MyTest(TestCase):
...     def setUp(self):
...         self.patcher1 = patch('package.module.Class1')
...         self.patcher2 = patch('package.module.Class2')
...         self.MockClass1 = self.patcher1.start()
...         self.MockClass2 = self.patcher2.start()
...
...     def tearDown(self):
...         self.patcher1.stop()
...         self.patcher2.stop()
...
...     def test_something(self):
...         assert package.module.Class1 is self.MockClass1
...         assert package.module.Class2 is self.MockClass2
...
>>> MyTest('test_something').run()

ご用心:

  この方式を使う場合、必ず "stop" メソッドを呼び出してパッチが解除する
  必要があります。 "setUp" の中で例外が発生した場合 "tearDown" が呼び
  出されないので、これは意外に面倒です。
  "unittest.TestCase.addCleanup()" を使うと簡単にできます:

  >>> class MyTest(TestCase):
  ...     def setUp(self):
  ...         patcher = patch('package.module.Class')
  ...         self.MockClass = patcher.start()
  ...         self.addCleanup(patcher.stop)
  ...
  ...     def test_something(self):
  ...         assert package.module.Class is self.MockClass
  ...

  この方式を使うと "patcher" オブジェクトの参照を維持する必要がなくな
  るという特典も付きます。

"patch.stopall()" を利用してすべての start されたパッチを stop するこ
ともできます。

patch.stopall()

   すべての有効なパッチを stop します。 "start" で開始したパッチしか
   stop しません。


26.5.3.6. ビルトインをパッチする
--------------------------------

モジュール内の任意のビルトインに対してパッチを当てることができます。以
下の例はビルトインの "ord()" を修正します:

>>> @patch('__main__.ord')
... def test(mock_ord):
...     mock_ord.return_value = 101
...     print(ord('c'))
...
>>> test()
101


26.5.3.7. TEST_PREFIX
---------------------

すべての patcher はクラスデコレータとして利用できます。この場合、その
クラスのすべてのテストメソッドをラップします。 patcher は "'test'" で
始まる名前のメソッドをテストメソッドだと認識します。これはデフォルトで
"unittest.TestLoader" がテストメソッドを見つける方法と同じです。

他の prefix を使う事もできます。その場合、 patcher にその prefix を
"patch.TEST_PREFIX" に設定することで教えることができます。

>>> patch.TEST_PREFIX = 'foo'
>>> value = 3
>>>
>>> @patch('__main__.value', 'not three')
... class Thing:
...     def foo_one(self):
...         print(value)
...     def foo_two(self):
...         print(value)
...
>>>
>>> Thing().foo_one()
not three
>>> Thing().foo_two()
not three
>>> value
3


26.5.3.8. patch デコレータをネストする
--------------------------------------

複数のパッチを行いたい場合、シンプルにデコレータを重ねることができます
。

次のパターンのように patch デコレータを重ねることができます:

>>> @patch.object(SomeClass, 'class_method')
... @patch.object(SomeClass, 'static_method')
... def test(mock1, mock2):
...     assert SomeClass.static_method is mock1
...     assert SomeClass.class_method is mock2
...     SomeClass.static_method('foo')
...     SomeClass.class_method('bar')
...     return mock1, mock2
...
>>> mock1, mock2 = test()
>>> mock1.assert_called_once_with('foo')
>>> mock2.assert_called_once_with('bar')

デコレータは下から上へと適用されることに注意してください。これは
Python がデコレータを適用する標準的な方法です。テスト関数に渡される生
成された mock の順番もこれに一致します。


26.5.3.9. どこにパッチするか
----------------------------

"patch()" は (一時的に) ある *名前* が参照しているオブジェクトを別のも
のに変更することで適用されます。任意のオブジェクトには、それを参照する
たくさんの名前が存在しえます。なので、必ずテスト対象のシステムが使って
いる名前に対して patch しなければなりません。

基本的な原則は、オブジェクトが *ルックアップ* されるところにパッチする
ことです。その場所はオブジェクトが定義されたところとは限りません。これ
を説明するためにいくつかの例を挙げます。

次のような構造を持ったプロジェクトをテストしようとしていると仮定してく
ださい:

   a.py
       -> Defines SomeClass

   b.py
       -> from a import SomeClass
       -> some_function instantiates SomeClass

いま、 "some_function" をテストしようとしていて、そのために
"SomeClass" を "patch()" を使って mock しようとしています。 モジュール
b をインポートした時点で、 b は "SomeClass" を a からインポートしてい
ます。この状態で "a.SomeClass" を "patch()" を使って mock out してもテ
ストには影響しません。モジュール b はすでに *本物の* "SomeClass" への
参照を持っていて、パッチの影響を受けないからです。

重要なのは、 "SomeClass" が使われている (もしくはルックアップされてい
る) 場所にパッチすることです。この場合、 "some_function" はモジュール
b の中にインポートされた "SomeClass" をルックアップしています。なので
パッチは次のようにしなければなりません:

   @patch('b.SomeClass')

ですが、別のシナリオとして、module b が "from a import SomeClass" では
なく "import a" をしていて、 "some_function" が "a.SomeClass" を利用し
ていたとします。どちらのインポートも一般的なものです。この場合、パッチ
したいクラスはそのモジュールからルックアップされているので、
"a.SomeClass" をパッチする必要があります:

   @patch('a.SomeClass')


26.5.3.10. デスクリプタやプロキシオブジェクトにパッチする
---------------------------------------------------------

patch と patch.object はどちらも デスクリプタ (クラスメソッド、static
メソッド、プロパティ) を正しく patch できます。デスクリプタに patch す
る場合、インスタンスではなく *class* にパッチする必要があります。これ
らはまた *幾らかの* 属性アクセスをプロキシするオブジェクト、例えば
django の setttings オブジェクト に対しても機能します。


26.5.4. MagicMock と magic method のサポート
============================================


26.5.4.1. magick method をモックする
------------------------------------

"Mock" は、 "magic method" とも呼ばれる、Python のプロトコルメソッドに
対する mock もサポートしています。これによりコンテナやその他 Python の
プロトコルを実装しているオブジェクトを mock することが可能になります。

magic method は通常のメソッドとはルックアップ方法が異なるので [2],
magic method のサポートは特別に実装されています。そのため、サポートさ
れているのは特定の magic method のみです。*ほとんど* すべてのメソッド
をサポートしていますが、足りないものを見つけたら私達に教えてください。

magic method を mock するには、対象の method に対して関数や mock のイ
ンスタンスをセットします。もし関数を使う場合、それは第一引数に "self"
を取る *必要があります* [3].

>>> def __str__(self):
...     return 'fooble'
...
>>> mock = Mock()
>>> mock.__str__ = __str__
>>> str(mock)
'fooble'

>>> mock = Mock()
>>> mock.__str__ = Mock()
>>> mock.__str__.return_value = 'fooble'
>>> str(mock)
'fooble'

>>> mock = Mock()
>>> mock.__iter__ = Mock(return_value=iter([]))
>>> list(mock)
[]

ユースケースの1つは "with" 文の中でコンテキストマネージャーとして使わ
れるオブジェクトを mock することです。

>>> mock = Mock()
>>> mock.__enter__ = Mock(return_value='foo')
>>> mock.__exit__ = Mock(return_value=False)
>>> with mock as m:
...     assert m == 'foo'
...
>>> mock.__enter__.assert_called_with()
>>> mock.__exit__.assert_called_with(None, None, None)

magic method の呼び出しは "method_calls" に含まれませんが、
"mock_calls" には記録されます。

注釈:

  mock を生成するのに *spec* キーワード引数を使った場合、 spec に含ま
  れない magic method を設定しようとすると "AttributeError" が発生しま
  す。

サポートしている magic method の完全なリスト:

* "__hash__", "__sizeof__", "__repr__", "__str__"

* "__dir__", "__format__", "__subclasses__"

* "__floor__", "__trunc__", "__ceil__"

* 比較: "__lt__", "__gt__", "__le__", "__ge__", "__eq__", "__ne__"

* コンテナメソッド: "__getitem__", "__setitem__", "__delitem__",
  "__contains__", "__len__", "__iter__", "__reversed__",
  "__missing__"

* コンテキストマネージャー: "__enter__", "__exit__"

* 単項算術メソッド: "__neg__", "__pos__", "__invert__"

* 算術メソッド (右辺や in-place のものも含む): "__add__", "__sub__",
  "__mul__", "__matmul__", "__div__", "__truediv__", "__floordiv__",
  "__mod__", "__divmod__", "__lshift__", "__rshift__", "__and__",
  "__xor__", "__or__", "__pow__"

* 算術変換メソッド: "__complex__", "__int__", "__float__",
  "__index__"

* デスクリプタメソッド: "__get__", "__set__", "__delete__"

* pickle: "__reduce__", "__reduce_ex__", "__getinitargs__",
  "__getnewargs__", "__getstate__", "__setstate__"

以下のメソッドは存在しますが、mock が利用している、動的に設定不可能、
その他の問題が発生する可能性があるなどの理由で *サポートされていません
*:

* "__getattr__", "__setattr__", "__init__", "__new__"

* "__prepare__", "__instancecheck__", "__subclasscheck__", "__del__"


26.5.4.2. Magic Mock
--------------------

"MagicMock" 系のクラスは2種類あります: "MagicMock" と
"NonCallableMagicMock" です。

class unittest.mock.MagicMock(*args, **kw)

   "MagicMock" は "Mock" のサブクラスで、ほとんどの magic method のデ
   フォルト実装を提供しています。自分で magic method を構成しなくても
   "MagicMock" を使うことができます。

   コンストラクタの引数は "Mock" と同じ意味を持っています。

   *spec* か *spec_set* 引数を利用した場合、 spec に存在する magic
   method *のみ* が生成されます。

class unittest.mock.NonCallableMagicMock(*args, **kw)

   callable でないバージョンの "MagicMock"

   コンストラクタの引数は "MagicMock" と同じ意味を持ちますが、
   *return_value* と *side_effect* は callable でない mock では意味を
   持ちません。

"MagicMock" が magic method をセットアップするので、あとは通常の方法で
構成したり利用したりできます:

>>> mock = MagicMock()
>>> mock[3] = 'fish'
>>> mock.__setitem__.assert_called_with(3, 'fish')
>>> mock.__getitem__.return_value = 'result'
>>> mock[2]
'result'

デフォルトでは、多くのプロトコルメソッドは特定の型の戻り値を要求されま
す。それらのメソッドではその型のデフォルトの戻り値がデフォルトの戻り値
として設定されているので、戻り値に興味が有る場合以外は何もしなくても利
用可能です。デフォルトの値を変更したい場合は手動で戻り値を設定可能です
。

メソッドとそのデフォルト値:

* "__lt__": NotImplemented

* "__gt__": NotImplemented

* "__le__": NotImplemented

* "__ge__": NotImplemented

* "__int__": 1

* "__contains__": False

* "__len__": 0

* "__iter__": iter([])

* "__exit__": False

* "__complex__": 1j

* "__float__": 1.0

* "__bool__": True

* "__index__": 1

* "__hash__": mock のデフォルトの hash

* "__str__": mock のデフォルトの str

* "__sizeof__": mock のデフォルトの sizeof

例えば:

>>> mock = MagicMock()
>>> int(mock)
1
>>> len(mock)
0
>>> list(mock)
[]
>>> object() in mock
False

2つの比較メソッド "__eq__()" と "__ne__()" は特別です。それらは、もし
戻り値として何か別のものを返すように変更していなければ、 "side_effect"
属性を使用して、同一性に基づくデフォルトの同値比較を行います:

   >>> MagicMock() == 3
   False
   >>> MagicMock() != 3
   True
   >>> mock = MagicMock()
   >>> mock.__eq__.return_value = True
   >>> mock == 3
   True

"MagickMock.__iter__()" の return_value は任意の iterable で、イテレー
タである必要はありません:

>>> mock = MagicMock()
>>> mock.__iter__.return_value = ['a', 'b', 'c']
>>> list(mock)
['a', 'b', 'c']
>>> list(mock)
['a', 'b', 'c']

return_value が iterator であった場合、最初のイテレートでその iterator
を消費してしまい、2回目以降のイテレートの結果が空になってしまいます:

>>> mock.__iter__.return_value = iter(['a', 'b', 'c'])
>>> list(mock)
['a', 'b', 'c']
>>> list(mock)
[]

"MagicMock" はいくつかの曖昧であったり時代遅れなものをのぞいて、対応し
ている magic method を事前にセットアップします。自動でセットアップされ
ていないものも必要なら手動でセットアップすることができます。

"MagicMock" がサポートしているもののデフォルトではセットアップしない
magic method:

* "__subclasses__"

* "__dir__"

* "__format__"

* "__get__", "__set__", "__delete__"

* "__reversed__", "__missing__"

* "__reduce__", "__reduce_ex__", "__getinitargs__", "__getnewargs__",
  "__getstate__", "__setstate__"

* "__getformat__", "__setformat__"

[2] Magic method はインスタンスではなくクラスからルックアップされるは
    ずです。Python のバージョンによってこのルールが適用されるかどうか
    に違いがあります。サポートされているプロトコルメソッドは、サポート
    されているすべての Python のバージョンで動作するはずです。

[3] 関数はクラスまで hook しますが、各 "Mock" インスタンス間の独立性は
    保たれます。


26.5.5. ヘルパー
================


26.5.5.1. sentinel
------------------

unittest.mock.sentinel

   "sentinel" オブジェクトはテストで必要なユニークなオブジェクトを簡単
   に提供します。

   属性はアクセス時にオンデマンドで生成されます。同じ属性に複数回アク
   セスすると必ず同じオブジェクトが返されます。返されるオブジェクトは
   、テスト失敗のメッセージがわかりやすくなるように気が利いた repr を
   持ちます。

      The "sentinel" attributes don't preserve their identity when
      they are "copied" or "pickled".

特定のオブジェクトが他のメソッドに引数として渡されることをテストしたり
、返されることをテストしたい場合があります。このテストのために名前がつ
いた sentinel オブジェクトを作るのが一般的です。 "sentinel" はこのよう
なオブジェクトを生成し、同一性をテストするのに便利な方法を提供します。

次の例では、 "method" が "sentinel.some_object" を返すようにモンキーパ
ッチしています:

>>> real = ProductionClass()
>>> real.method = Mock(name="method")
>>> real.method.return_value = sentinel.some_object
>>> result = real.method()
>>> assert result is sentinel.some_object
>>> sentinel.some_object
sentinel.some_object


26.5.5.2. DEFAULT
-----------------

unittest.mock.DEFAULT

   "DEFAULT" オブジェクトは事前に生成された sentinel (実際には
   "sentinel.DEFAULT") オブジェクトです。 "side_effect" 関数が、通常の
   戻り値を使うことを示すために使います。


26.5.5.3. call
--------------

unittest.mock.call(*args, **kwargs)

   "call()" は "call_args", "call_args_list", "mock_calls",
   "method_calls" と比較してより下端に assert できるようにするためのヘ
   ルパーオブジェクトです。 "call()" は "assert_has_calls()" と組み合
   わせて使うこともできます。

   >>> m = MagicMock(return_value=None)
   >>> m(1, 2, a='foo', b='bar')
   >>> m()
   >>> m.call_args_list == [call(1, 2, a='foo', b='bar'), call()]
   True

call.call_list()

   複数回の呼び出しを表す call オブジェクトに対して、 "call_list()" は
   すべての途中の呼び出しと最終の呼び出しを含むリストを返します。

"call_list" は特に "chained call" に対して assert するのに便利です。
"chained call" は1行のコードにおける複数の呼び出しです。この結果は
mock の "mock_calls" に複数の call エントリとして格納されます。この
call のシーケンスを手動で構築するのは退屈な作業になります。

"call_list()" は同じ chained call からその call のシーケンスを構築する
ことができます:

>>> m = MagicMock()
>>> m(1).method(arg='foo').other('bar')(2.0)
<MagicMock name='mock().method().other()()' id='...'>
>>> kall = call(1).method(arg='foo').other('bar')(2.0)
>>> kall.call_list()
[call(1),
 call().method(arg='foo'),
 call().method().other('bar'),
 call().method().other()(2.0)]
>>> m.mock_calls == kall.call_list()
True

"call" オブジェクトは、どう構築されたかによって、 (位置引数、キーワー
ド引数) のタプルか、 (名前、位置引数、キーワード引数) のタプルになりま
す。自分で call オブジェクトを構築するときはこれを意識する必要はありま
せんが、 "Mock.call_args", "Mock.call_args_list", "Mock.mock_calls" 属
性の中の "call" オブジェクトを解析して個々の引数を解析することができま
す。

"Mock.call_args" と "Mock.call_args_list" の中の "call" オブジェクトは
(位置引数, キーワード引数) のタプルで、 "Mock.mock_calls" の中の
"call" オブジェクトや自分で構築したオブジェクトは (名前, 位置引数, キ
ーワード引数) のタプルになります。

call オブジェクトの "タプル性" を使って、より複雑な内省とアサートを行
うために各引数を取り出しすことができます。位置引数はタプル (位置引数が
存在しない場合は空のタプル) で、キーワード引数は辞書になります:

>>> m = MagicMock(return_value=None)
>>> m(1, 2, 3, arg='one', arg2='two')
>>> kall = m.call_args
>>> args, kwargs = kall
>>> args
(1, 2, 3)
>>> kwargs
{'arg2': 'two', 'arg': 'one'}
>>> args is kall[0]
True
>>> kwargs is kall[1]
True

>>> m = MagicMock()
>>> m.foo(4, 5, 6, arg='two', arg2='three')
<MagicMock name='mock.foo()' id='...'>
>>> kall = m.mock_calls[0]
>>> name, args, kwargs = kall
>>> name
'foo'
>>> args
(4, 5, 6)
>>> kwargs
{'arg2': 'three', 'arg': 'two'}
>>> name is m.mock_calls[0][0]
True


26.5.5.4. create_autospec
-------------------------

unittest.mock.create_autospec(spec, spec_set=False, instance=False, **kwargs)

   他のオブジェクトを spec として利用して mock オブジェクトを作ります
   。 mock の属性も、 *spec* オブジェクトの該当する属性を spec として
   利用します。

   mock された関数やメソッドは、正しいシグネチャで呼び出されたことを確
   認するために引数をチェックします。

   *spec_set* が "True" のとき、 spec オブジェクトにない属性をセットし
   ようとすると "AttributeError" を発生させます。

   spec にクラスが指定された場合、 mock の戻り値 (そのクラスのインスタ
   ンス) は同じ spec を持ちます。 "instance=True" を指定すると、インス
   タンスオブジェクトの spec としてクラスを利用できます。返される mock
   は、モックのインスタンスが callable な場合にだけ callable となりま
   す。

   "create_autospec()" は任意のキーワード引数を受け取り、生成する mock
   のコンストラクタに渡します。

"create_autospec()" や、 "patch()" の *autospec* 引数で autospec を使
うサンプルは autospec を使う を参照してください。


26.5.5.5. ANY
-------------

unittest.mock.ANY

mock の呼び出しのうち *幾つか* の引数に対して assert したいけれども、
それ以外の引数は気にしない、あるいは "call_args" から個別に取り出して
より高度な assert を行いたい場合があります。

特定の引数を無視するために、 *すべて* と等しくなるオブジェクトを使うこ
とができます。そうすると、 "assert_called_with()" と
"assert_called_once_with()" は、実際の引数が何であったかに関わらず成功
します。

>>> mock = Mock(return_value=None)
>>> mock('foo', bar=object())
>>> mock.assert_called_once_with('foo', bar=ANY)

"mock_calls" などの call list との比較に "ANY" を使うこともできます:

>>> m = MagicMock(return_value=None)
>>> m(1)
>>> m(1, 2)
>>> m(object())
>>> m.mock_calls == [call(1), call(1, 2), ANY]
True


26.5.5.6. FILTER_DIR
--------------------

unittest.mock.FILTER_DIR

"FILTER_DIR" は mock オブジェクトが "dir()" に何を返すかを制御するため
のモジュールレベル変数です。 (Python 2.6 以上でのみ有効) デフォルトは
"True" で、以下に示すフィルタリングを行い、有用なメンバーだけを表示し
ます。このフィルタリングが嫌な場合や、何かの診断のためにフィルタリング
を切りたい場合は、 "mock.FILTER_DIR = False" と設定してください。

フィルタリングが有効な場合、 "dir(some_mock)" は有用な属性だけを表示し
、また通常は表示されない動的に生成される属性も表示します。 mock が
*spec* を使って(もちろん *autospec* でも)生成された場合、元のオブジェ
クトのすべての属性が、まだアクセスされていなかったとしても、表示されま
す。

>>> dir(Mock())
['assert_any_call',
 'assert_called_once_with',
 'assert_called_with',
 'assert_has_calls',
 'attach_mock',
 ...
>>> from urllib import request
>>> dir(Mock(spec=request))
['AbstractBasicAuthHandler',
 'AbstractDigestAuthHandler',
 'AbstractHTTPHandler',
 'BaseHandler',
 ...

多くのあまり有用ではない (mock 対象のものではなく、 "Mock" 自身のプラ
イベートな) 属性は、アンダースコアと2つのアンダースコアで prefix され
た属性は "Mock" に対して "dir()" した結果からフィルタリングされます。
この動作が嫌な場合は、モジュールレベルの "FILTER_DIR" スイッチを設定す
ることでフィルターを切ることができます。

>>> from unittest import mock
>>> mock.FILTER_DIR = False
>>> dir(mock.Mock())
['_NonCallableMock__get_return_value',
 '_NonCallableMock__get_side_effect',
 '_NonCallableMock__return_value_doc',
 '_NonCallableMock__set_return_value',
 '_NonCallableMock__set_side_effect',
 '__call__',
 '__class__',
 ...

"mock.FILTER_DIR" によるフィルタリングをバイパスしたい場合、
"var(my_mock)" (インスタンスメンバー)、 "dir(type(my_mock))" (型メンバ
ー) を代わりに使うことができます。


26.5.5.7. mock_open
-------------------

unittest.mock.mock_open(mock=None, read_data=None)

   "open()" の利用を置き換えるための mock を作るヘルパー関数。
   "open()" を直接呼んだりコンテキストマネージャーとして利用する場合に
   使うことができます。

   *mock* 引数は構成する mock オブジェクトです。 "None" (デフォルト)
   なら、通常のファイルハンドルと同じ属性やメソッドにAPIが制限された
   "MagicMock" が生成されます。

   *read_data* は、ファイルハンドルの "read()", "readline()", そして
   "readlines()" のメソッドが返す文字列です。これらのメソッドを呼び出
   すと、読み出し終わるまで *read_data* からデータが読み出されます。こ
   れらモックのメソッドはとても単純化されています: *mock* が呼ばれるた
   びに *read_data* は先頭に巻き戻されます。テストコードに与えるデータ
   をさらにコントロールするには自分自身でモックをカスタマイズする必要
   があります。それでも不十分な場合は、 PyPI にあるインメモリファイル
   システムパッケージのうちのどれかを使えば、テストのための本物のファ
   イルシステムが得られるでしょう。

   バージョン 3.4 で変更: "readline()" および "readlines()" のサポート
   が追加されました。 "read()" のモックは、個々の呼び出しで
   *read_data* を返すのではなく、それを消費するように変わりました。

   バージョン 3.5 で変更: *read_data* は *mock* を呼び出す度に毎回リセ
   ットされるようになりました。

"open()" をコンテキストマネージャーとして使う方法は、ファイルが必ず適
切に閉じられるようにする素晴らしい方法で、今では一般的になっています:

   with open('/some/path', 'w') as f:
       f.write('something')

問題は、 "open()" をモックアウトしたところで、コンテキストマネージャー
が使われる ("__enter__()" と "__exit__()" が呼ばれる) のはその *戻り値
* だということです。

コンテキストマネージャーを "MagicMock" でモックするのは一般的かつ面倒
なので、ヘルパー関数を用意しています。

>>> m = mock_open()
>>> with patch('__main__.open', m):
...     with open('foo', 'w') as h:
...         h.write('some stuff')
...
>>> m.mock_calls
[call('foo', 'w'),
 call().__enter__(),
 call().write('some stuff'),
 call().__exit__(None, None, None)]
>>> m.assert_called_once_with('foo', 'w')
>>> handle = m()
>>> handle.write.assert_called_once_with('some stuff')

ファイルの読み込みをモックする例:

>>> with patch('__main__.open', mock_open(read_data='bibble')) as m:
...     with open('foo') as h:
...         result = h.read()
...
>>> m.assert_called_once_with('foo')
>>> assert result == 'bibble'


26.5.5.8. autospec を使う
-------------------------

autospec は mock の "spec" 機能を基盤にしています。 autospec は mock
の API を元のオブジェクト (spec) に制限しますが、再帰的に適用される
(lazy に実装されている) ので、 mock の属性も spec の属性と同じ API だ
けを持つようになります。さらに、 mock された関数/メソッドは元と同じシ
グネチャを持ち、正しくない引数で呼び出されると "TypeError" を発生させ
ます。

autospec の動作について説明する前に、それが必要となる背景から説明して
いきます。

"Mock" は非常に強力で柔軟なオブジェクトですが、テスト対象のシステムを
モックアウトするときに2つの欠点があります。 1つ目の欠点は "Mock" の
API に関したもので、もう一つは mock オブジェクトを使う場合のもっと一般
的な問題です。

まず "Mock" 独自の問題から解説します。 "Mock" は便利な2つのメソッド、
"assert_called_with()" と "assert_called_once_with()" を持っています。

>>> mock = Mock(name='Thing', return_value=None)
>>> mock(1, 2, 3)
>>> mock.assert_called_once_with(1, 2, 3)
>>> mock(1, 2, 3)
>>> mock.assert_called_once_with(1, 2, 3)
Traceback (most recent call last):
 ...
AssertionError: Expected 'mock' to be called once. Called 2 times.

mock が属性をオンデマンドに自動生成し、それを任意の引数で呼び出せるた
め、それらの assert メソッドのいずれかをミススペルするとその assert の
効果が消えてしまいます:

   >>> mock = Mock(name='Thing', return_value=None)
   >>> mock(1, 2, 3)
   >>> mock.assret_called_once_with(4, 5, 6)

typo のために、テストは不正確に、かつ暗黙に成功してしまいます。

2つ目の問題はもっと一般的なものです。なにかのコードをリファクタし、メ
ンバの名前を変更したとします。*古いAPI* を利用したコードに対するテスト
が、mock を利用しているとするとテストは通り続けます。このため、コード
が壊れていてもテストがすべて通ってしまう可能性があります。

各ユニットが互いにどのように接続されるかをテストしない場合、依然として
テストで見つけることができるバグの余地が多く残っています。

"mock" はこの問題に対処するために spec と呼ばれる機能を提供しています
。何かクラスかインスタンスを "spec" として mock に渡すと、実際のクラス
に存在する属性にしか、 mock に対してもアクセスできなくなります:

>>> from urllib import request
>>> mock = Mock(spec=request.Request)
>>> mock.assret_called_with
Traceback (most recent call last):
 ...
AttributeError: Mock object has no attribute 'assret_called_with'

spec はその mock 自体にしか適用されません。なので、同じ問題がその mock
のすべてのメソッドに対して発生します:

   >>> mock.has_data()
   <mock.Mock object at 0x...>
   >>> mock.has_data.assret_called_with()

autospec はこの問題を解決します。 "patch()" か "patch.object()" に
"autospec=True" を渡すか、 "create_autospec()" 関数を使って spec をも
とに mock を作ることができます。 "patch()" の引数に "autospec=True" を
渡した場合、置換対象のオブジェクトが spec オブジェクトとして利用されま
す。 spec は遅延処理される (mock の属性にアクセスされた時に spec が生
成される) ので、非常に複雑だったり深くネストしたオブジェクト (例えばモ
ジュールをインポートするモジュールをインポートするモジュール) に対して
も大きなパフォーマンスの問題なしに autospec を使うことができます。

autospec の利用例:

>>> from urllib import request
>>> patcher = patch('__main__.request', autospec=True)
>>> mock_request = patcher.start()
>>> request is mock_request
True
>>> mock_request.Request
<MagicMock name='request.Request' spec='Request' id='...'>

"request.Request" が spec を持っているのが分かります。
"request.Request" のコンストラクタは2つの引数を持っています (片方は
*self* です)。コンストラクタを間違って呼び出した時に何が起こるでしょう
か:

>>> req = request.Request()
Traceback (most recent call last):
 ...
TypeError: <lambda>() takes at least 2 arguments (1 given)

spec はクラスがインスタンス化されたとき (つまり spec が適用された mock
の戻り値) にも適用されます:

>>> req = request.Request('foo')
>>> req
<NonCallableMagicMock name='request.Request()' spec='Request' id='...'>

"Request" オブジェクトは callable ではないので、 "request.Request" の
mock から返されたインスタンスの mock は callable ではなくなります。
spec があれば、 assert のミススペルは正しいエラーを発生させます:

>>> req.add_header('spam', 'eggs')
<MagicMock name='request.Request().add_header()' id='...'>
>>> req.add_header.assret_called_with
Traceback (most recent call last):
 ...
AttributeError: Mock object has no attribute 'assret_called_with'
>>> req.add_header.assert_called_with('spam', 'eggs')

多くの場合、単に既存の "patch()" 呼び出しに "autospec=True" を加えるだ
けで、ミススペルやAPI変更に伴うバグから守られます。

"patch()" を経由する以外にも、 "create_autospec()" を使って *autospec*
が適用された mock を直接作る方法もあります:

>>> from urllib import request
>>> mock_request = create_autospec(request)
>>> mock_request.Request('foo', 'bar')
<NonCallableMagicMock name='mock.Request()' spec='Request' id='...'>

とはいえ、autospec には注意しなければならない点や制限があり、そのため
デフォルトでは無効になっています。spec オブジェクトでどんな属性が使え
るかどうかを調べるために、autospec は spec オブジェクトをイントロスペ
クト (実際に属性にアクセスする) 必要があります。mock の属性を利用する
とき、水面下で元のオブジェクトに対しても同じ属性の探索が行われます。
spec したオブジェクトのどれかがコードを実行するプロパティやデスクリプ
タを持っている場合、autospec は正しく動きません。もしくは、イントロス
ペクションしても安全なようにオブジェクトを設計するのがよいでしょう [4]
。

より重大な問題は、インスタンス属性が "__init__()" で生成され、クラスに
は全く存在しない場合です。 *autospec* は動的に生成される属性については
知ることができず、 API を検出できる属性だけに制限してしまいます。

>>> class Something:
...   def __init__(self):
...     self.a = 33
...
>>> with patch('__main__.Something', autospec=True):
...   thing = Something()
...   thing.a
...
Traceback (most recent call last):
  ...
AttributeError: Mock object has no attribute 'a'

この問題を解決するためにいくつかの方法があります。一番簡単な、ただし一
番面倒でないとは限らない方法は、必要とされる属性を mock が生成された後
に設定することです。 *autospec* は属性を参照することを禁止しますが、設
定することは禁止していません:

>>> with patch('__main__.Something', autospec=True):
...   thing = Something()
...   thing.a = 33
...

*spec* と *autospec* にはよりアグレッシブなバージョンがあり、存在しな
い属性への設定も禁止します。これはコードが正しい属性にのみ代入すること
を保証したいときに便利ですが、もちろん先ほどの方法も制限されてしまいま
す:

>>> with patch('__main__.Something', autospec=True, spec_set=True):
...   thing = Something()
...   thing.a = 33
...
Traceback (most recent call last):
 ...
AttributeError: Mock object has no attribute 'a'

この問題を解決するベストな方法は、 "__init__()" で初期化されるインスタ
ンスメンバに対する初期値をクラス属性として追加することかもしれません。
"__init__()" メソッドの中でデフォルトの属性を代入しているだけなら、そ
れをクラス属性にする (この属性はもちろんインスタンス間で共有されます)
方が速くなるのもメリットです。例:

   class Something:
       a = 33

クラス属性を使ってもまた別の問題があります。メンバーのデフォルト値に
"None" を利用し、後から別の型のオブジェクトを代入するのは比較的よくあ
るパターンです。 spec として "None" を使うと *すべての* 属性やメソッド
へのアクセスも許されなくなるので使い物になりません。 "None``を spec に
することが有用な場面は *決して* なく、おそらくそのメンバーは他の何かの
型のメンバーになることを示すので、 autospec は ``None" に設定されてい
るメンバーには spec を使いません。その属性は通常の mock (MagicMocks)
になります。

>>> class Something:
...     member = None
...
>>> mock = create_autospec(Something)
>>> mock.member.foo.bar.baz()
<MagicMock name='mock.member.foo.bar.baz()' id='...'>

すでに利用されているクラスにデフォルト値属性を追加するのが嫌な場合は、
他の選択肢もあります。選択肢の1つは、クラスではなくインスタンスを spec
に使うことです。別の選択肢は、実際のクラスのサブクラスを作り、実際に利
用されている方に影響を与えずにデフォルト値属性を追加することです。どち
らの方法も spec として代替オブジェクトを利用することが必要です。
"patch()" はこれをサポートしていて、 *autospec* 引数に代替オブジェクト
を渡すことができます。

>>> class Something:
...   def __init__(self):
...     self.a = 33
...
>>> class SomethingForTest(Something):
...   a = 33
...
>>> p = patch('__main__.Something', autospec=SomethingForTest)
>>> mock = p.start()
>>> mock.a
<NonCallableMagicMock name='Something.a' spec='int' id='...'>

[4] これはクラスやすでにインスタンス化されたオブジェクトにだけ当てはま
    ります。 mock されたクラスを呼び出して mock インスタンスを作っても
    、実際のオブジェクトのインスタンスは生成されません。 mock は属性を
    - "dir()" を呼び出して - 検索するだけです。
