2016-10-25 8 views
1
from mock import Mock 
j = [] 
u = Mock() 
u(j) 
# At this point u.call_args_list == [call([])] 
print u.call_args_list 
j.append(100) 
# At this point u.call_args_list == [call([100])], but I expect it to be [call([])], since it was never called when j had a value of 100 in it 
print u.call_args_list 

私の質問は、u.call_args_listのコールに、モックの引数をチェックしているときではなく、モックを呼び出すときにすべてのオブジェクトの状態が含まれていることを確認するにはどうすればいいですか?Mockオブジェクトが呼び出されたのと同じ状態で、Mock.call_args_listの呼び出しに引数付きの呼び出しが含まれていることを、どのように保証するのですか?

私は現時点でmock==1.0.1を使用しています。

答えて

1

これについては、ドキュメントのセクション26.6.3.7. Coping with mutable argumentsで説明しています。

残念ながら、彼らは本当に問題に洗練された解決策を持っていません!推奨される回避策は、side_effectを使用して、可変引数から要素をコピーすることです。

モックにside_effect関数を指定すると、モックと同じargsでside_effectが呼び出されます。これにより、引数をコピーして後でアサーション用に格納する機会が与えられます。

私の意見では、やや乱雑です。

from copy import deepcopy 

class CopyingMock(MagicMock): 
    def __call__(self, *args, **kwargs): 
     args = deepcopy(args) 
     kwargs = deepcopy(kwargs) 
     return super(CopyingMock, self).__call__(*args, **kwargs) 

を:あなたが複数の場所での能力が必要な場合は、Mockをサブクラス化し、直接機能を追加することを好むかもしれそれは、サードパーティの分布(pip install copyingmock)で使用できるようになりましたです。

>>> from copyingmock import CopyingMock 
>>> mock = CopyingMock() 
>>> list_ = [1,2] 
>>> mock(list_) 
<CopyingMock name='mock()' id='4366094008'> 
>>> list_.append(3) 
>>> mock.assert_called_once_with([1,2]) 
>>> mock.assert_called_once_with(list_) 

AssertionError: Expected call: mock([1, 2, 3]) 
Actual call: mock([1, 2]) 
関連する問題