1. ホーム
  2. python

[解決済み] クラスをモック化する。Mock()かpatch()か?

2022-04-28 12:20:27

質問

を使っています。 模擬 Pythonで、この2つのアプローチのどちらが良いのか(よりPythonicなのか)疑問に思っていました。

方法1 : モックオブジェクトを作って、それを使うだけです。コードはこんな感じ。

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

方法2 : patchを使用してモックを作成します。 コードはこんな感じ。

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

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

どなたか教えてください。

どのように解決するのですか?

mock.patch とは全く異なる生物である。 mock.Mock . patch 置き換える を使うと、クラスをモックオブジェクトに変換し、そのモックインスタンスを操作できるようになります。 このスニペットを見てください。

>>> 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>

patch 置き換える MyClass を使用することで、呼び出す関数でのクラスの使用を制御することができます。 クラスにパッチを当てると、そのクラスへの参照はモックインスタンスに完全に置き換えられます。

mock.patch は、通常、テスト内でクラスの新しいインスタンスを作成するようなテストをするときに使用します。 mock.Mock のインスタンスの方が明確であり、好まれます。 もし self.sut.something のインスタンスを作成しました。 MyClass インスタンスをパラメータとして受け取る代わりに mock.patch が適切であろう。