次のコードを検討し、クラスメソッドの交換(ない非常に良いデザインを、それがポイントです):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
に関係していると思いますので、豊富な機能をすべて備えたこのライブラリを適切に使用するためには、この機能を理解することが重要です。
誰かが手がかりを持っていますか?