問題描述
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
中的調用在調用模擬時而不是在檢查模擬參數時包含所有對象的狀態?
My question is how do I ensure that the calls in u.call_args_list
contain the states of all objects at the time of calling the mock rather than at the time of checking the arguments of the mock?
我目前正在使用 mock==1.0.1
.
推薦答案
這在文檔部分進行了討論 26.6.3.7.處理可變參數.
This is discussed in the documentation section 26.6.3.7. Coping with mutable arguments.
不幸的是,他們對這個問題并沒有任何優雅的解決方案!推薦的解決方法是使用 side_effect
從可變參數中復制元素.
Unfortunately, they don't really have any elegant solution to the issue! The recommended workaround is copying elements from the mutable arguments by using side_effect
.
如果您為模擬提供了一個 side_effect 函數,那么將使用與模擬相同的參數調用 side_effect.這使我們有機會復制參數并將它們存儲起來以供以后斷言.
If you provide a side_effect function for a mock then side_effect will be called with the same args as the mock. This gives us an opportunity to copy the arguments and store them for later assertions.
在我看來,實施起來有些混亂.如果您在多個地方需要該功能,您可能更愿意繼承 Mock
并直接添加該功能:
It's somewhat messy to implement, in my opinion. If you need the capability in multiple places, you may prefer to subclass Mock
and add the feature directly:
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)
<小時>
2017:它現在可以在第三方發行版中使用(pip install copyingmock
).
2017: It's now available in a third-party distribution (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])
這篇關于我們如何確保 Mock.call_args_list 中的調用包含具有與調用 Mock 對象時相同狀態的參數的調用?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!