2017-07-19 4 views
0

次のコードを検討し、クラスメソッドの交換(ない非常に良いデザインを、それがポイントです):Pythonのモック:

class A(object): 
    def __init__(self,filepath): 
     self._access_file_system(filepath) 

    def get(self): 
     return self._result_dict 


class B(object): 
    def __init__(self,filepath1,filepath2): 
     self._filepath1 = filepath1 
     self._filepath2 = filepath2 

    def foo(self): 
     a1 = A(self._filepath1).get() 
     a2 = A(self._filepath2).get() 
     return a1['result']==a2['result'] 

を今、私はB.foo()をテストしたい場合は、私のように(Aを模擬する必要がありますコンストラクタ内のファイルシステムにアクセスします)。ケースa1.get()a2.get()B.foo()戻っFalseは異なる値を提供することを確認するテストを記述するために

、私はまた、B.get()を模擬する必要があります。

ので、テスト機能は、おそらく次のようになります。

import mock 
mock_get = mock.MagicMock(side_effect=[{'result': 0}, {'result': 1}]) 

@mock.patch('__main__.A') 
def test_foo(MockA): 

    b = B('/file1','/file2') 
    res = b.foo() 
    assert res 
    MockA.assert_any_call('/file1') 
    MockA.assert_any_call('/file2') 

    #Doesn't work - 
    #the assignment doesn't propagate into the objects instantiated inside foo() 
    #A.get = mock_get 

    #The assigned method propagates into the class definition, 
    #so it works - BUT WHY?! 
    a = A(None) 
    a.get = mock_get 

    b = B('/file1', '/file2') 
    res = b.foo() 
    assert not res 

さて、奇妙なポイント - コード内のコメントからもわかるように、私たちはクラスにmock_getを割り当てた場合、それは勝ちました伝播しませんが、インスタンスを作成してそれに割り当てると、クラスの他のインスタンスに伝播します。

この動作は内部メカニズムmockに関係していると思いますので、豊富な機能をすべて備えたこのライブラリを適切に使用するためには、この機能を理解することが重要です。

誰かが手がかりを持っていますか?

答えて

1

最初のケースでは、getの方法にパッチを当てているところはありません。 Bが呼び出される前に、getメソッドのモック値をAに割り当てる必要があります。例えば、なぜ次の試験は

import mock 
mock_get = mock.MagicMock(side_effect=[{'result': 0}, {'result': 1}]) 

@mock.patch('__main__.A') 
def test_foo(MockA): 

    MockA.get = mock_get 

    b = B('/file1','/file2') 
    res = b.foo() 
    assert not res 
    MockA.assert_any_call('/file1') 
    MockA.assert_any_call('/file2') 

前挙動の理由は、我々は代わりに、オブジェクト自体、この場合MockAにおいて、物体(A)の戻り値にパッチを適用するために忘れていることである?:失敗しません(MockA)。 AオブジェクトはAクラスをインスタンス化した結果で、Aクラスのreturn_valueのメソッドにアクセスする必要があります。 (私が書いた)

関連する問題