クラスのモック化: Mock() か patch() か? 質問する

クラスのモック化: Mock() か patch() か? 質問する

使っていますモックPython を使用していて、どちらのアプローチが優れているか (つまり、より Python 的であるか) 疑問に思っていました。

方法1: モックオブジェクトを作成してそれを使用するだけです。コードは次のようになります。

def test_one (self):
    mock = Mock()
    mock.method.return_value = True 
    
    # This should call mock.method and check the result. 
    self.sut.something(mock) 

    self.assertTrue(mock.method.called)

方法2: patch を使用してモックを作成します。コードは次のようになります。

@patch("MyClass")
def test_two (self, mock):
    instance = mock.return_value
    instance.method.return_value = True
    
    # This should call mock.method and check the result.
    self.sut.something(instance) 

    self.assertTrue(instance.method.called)

どちらの方法も同じことを行います。違いがよくわかりません。

誰か私に教えてくれませんか?

ベストアンサー1

mock.patchは とは非常に異なる生き物ですmock.Mockpatch 置き換えるクラスにモック オブジェクトを追加し、モック インスタンスを操作できるようにします。次のスニペットをご覧ください。

>>> class MyClass(object):
...   def __init__(self):
...     print 'Created MyClass@{0}'.format(id(self))
... 
>>> def create_instance():
...   return MyClass()
... 
>>> x = create_instance()
Created MyClass@4299548304
>>> 
>>> @mock.patch('__main__.MyClass')
... def create_instance2(MyClass):
...   MyClass.return_value = 'foo'
...   return create_instance()
... 
>>> i = create_instance2()
>>> i
'foo'
>>> def create_instance():
...   print MyClass
...   return MyClass()
...
>>> create_instance2()
<mock.Mock object at 0x100505d90>
'foo'
>>> create_instance()
<class '__main__.MyClass'>
Created MyClass@4300234128
<__main__.MyClass object at 0x100505d90>

patchMyClass呼び出す関数内でのクラスの使用を制御できる方法で置き換えます。クラスにパッチを適用すると、クラスへの参照はモック インスタンスに完全に置き換えられます。

mock.patchは通常、テスト内でクラスの新しいインスタンスを作成するものをテストするときに使用されます。インスタンスの方が明確で、こちらが推奨されます。メソッドがパラメータとしてインスタンスを受け取るのではなく、のインスタンスを作成するmock.Mock場合は、ここで が適切です。self.sut.somethingMyClassmock.patch

おすすめ記事