2017-01-13 5 views
2

クラス内に複数のメソッドをパッチしようとしています。ここに私の設定簡略化されてPython Mockクラス内に複数のメソッドをパッチします

Hook.pyは、私は方法がフッククラスにget_keyとGET_VALUEモックとしたい

from Hook import Hook 

class HookTransfer(): 
    def execute(self): 
     self.hook = Hook() 
     key = self.hook.get_key() 
     value = self.hook.get_value() 
     print(key) 
     print(value) 

として定義

class Hook(): 
    def get_key(self): 
     return "Key" 

    def get_value(self): 
     return "Value" 

HookTransfer.pyとして定義されます。 New_KeyとNew_Valueを印刷します。

from HookTransfer import HookTransfer 
import unittest 
from unittest import mock 

class TestMock(unittest.TestCase): 
    @mock.patch('HookTransfer.Hook.get_key', return_value="New_Key") 
    @mock.patch('HookTransfer.Hook.get_value', return_value="New_Value") 
    def test_execute1(self, mock_get_key, mock_get_value): 
     HookTransfer().execute() 

if __name__ == '__main__': 
    unittest.main() 

ただし、これは動作しません。なお、第2の1があまりにも動作するはずですが、それはdoesntのように直感的にそれはそう<MagicMock name='Hook().get_key()' id='4317706896'><MagicMock name='Hook().get_value()' id='4317826128'>

from HookTransfer import HookTransfer 
import unittest 
from unittest import mock 

class TestMock(unittest.TestCase): 
    @mock.patch('HookTransfer.Hook', spec=True) 
    def test_execute2(self, mock_hook): 
     mock_hook.get_key = mock.Mock(return_value="New_Key") 
     mock_hook.get_value = mock.Mock(return_value="New_Value") 
     HookTransfer().execute() 

if __name__ == '__main__': 
    unittest.main() 

を印刷します。それがなぜそうでないのか説明するのを助けてください。私はそれが"where to patch"と関係があると思うが、私は明瞭さを得ることができない。

+0

一貫性のない何かがここにあります...あなたの最初の例では、 'インポートHookTransfer'(名前であるように思われしかし、あなたは '' HookTransfer import HookTransfer'を持っているかのように)テスト中のモジュールを呼び出します。 – mgilson

+0

私はより手の込んだコードを書いていました。上記の新しいコードを具体的にテストして貼り付けました。結果は同じです。指摘してくれてありがとう。 – kvb

答えて

0

いくつかのテストの後、私は問題を見つけることができました。

2番目のテストケースでは、パッチデコレータはMockクラスの新しいインスタンスを作成し、mock_hook引数を介してtest_execute2関数に渡します。これをmock1と呼ぶことにする。 mock1は、HookTransfer.pyのHookクラスを置き換えます。 self.hook = Hook()を実行すると、mock1の__init__が呼び出されます。設計上これはもう一つのモックインスタンスを返します - これをmock2と呼ぶことができます。だからself.hookはmock2を指しています。しかし、mock_hook.get_key = mock.Mock(return_value="New_Key")は、mock1のメソッドをモックします。

モックを正しく模倣するためには、モック2にパッチを当てる必要があります。これは、(mock2を返す)mock1のコンストラクタの戻り値の下mock_hook().get_key = mock.Mock(return_value="New_Key")

をモック(mock2返す)mock1のRETURN_VALUE mock_hook.return_value.get_key = mock.Mock(return_value="New_Key")

  • をモックすることにより、2つの方法
    1. で行うことができ両方のオプションを実際に同じことをラップします。あなたがする必要がどのような

  • 2

    です:

    モッククラスフック、

    from HookTransfer import HookTransfer 
    from Hook import Hook 
    
    import unittest 
    import mock 
    
    class TestMock(unittest.TestCase): 
        @mock.patch.object(Hook, 'get_key', return_value="New_Key") 
        @mock.patch.object(Hook, 'get_value', return_value="New_Value") 
        def test_execute1(self, mock_get_key, mock_get_value): 
         HookTransfer().execute() 
    
    if __name__ == "__main__": 
        unittest.main() 
    
    関連する問題