[英]Mocking nested properties with mock
我有一個函數調用返回一個對象:
r = Foo(x,y)
其中r
具有豐富的嵌套屬性集。 例如,我可以訪問r.prop_a.prop_b.prop_c
。 我想模擬Foo
,這樣r
的特定葉屬性被修改,即r.prop_a.prop_b.prop_c
返回一個我控制下的值:
>> r = Foo(x,y)
>> r.prop_a.prop_b.prop_c
'fish'
>> # some mock magic patching of Foo is taking place here
>> r = Foo(x,y)
>> r.prop_a.prop_b.prop_c
'my_fish'
我不太關心中間性質。
有沒有一種優雅的方式來模擬嵌套屬性與mock ?
像您期望的那樣替換模擬對象的屬性調用:
>> r1 = r_original(x, y)
>> r1.prop_a.prop_b.prop_c
'fish'
>> returner = mock.MagicMock()
>> returner.prop_a.prop_b.prop_c = 'fish'
>> r_mocked = mock.MagicMock(spec_set=r_original, return_value=returner)
>> r2 = r_mocked(x, y)
>> r2.prop_a.prop_b
MagicMock name='returner.prop_a.prop_b' id='87412560'>
>> r2.prop_a.prop_b.prop_c
'fish'
這樣可以在定義特定值時充分發揮模擬功能。
如果要在其他位置公開原始屬性,可以定義包裝類:
class OverrideAttributePath(object):
"""A proxy class where we override a specific attribute path with the
value given. For any other attribute path, we just return
attributes on the wrapped object.
"""
def __init__(self, thing, path, value):
self._thing = thing
self._path = path
self._value = value
def __dir__(self):
return dir(self._thing)
def __len__(self):
return len(self._thing)
def __getitem__(self, index):
if self._path == [index]:
return self._value
elif self._path[0] == index:
return OverrideAttributePath(
self._thing[index], self._path[1:], self._value)
else:
return self._thing[index]
def __getattr__(self, key):
if self._path == [key]:
return self._value
elif self._path[0] == key:
return OverrideAttributePath(
getattr(self._thing, key), self._path[1:], self._value)
else:
return getattr(self._thing, key)
用法如下:
>>> r = Foo(x,y)
>>> r2 = OverrideAttributePath(r, ['prop_a', 'prop_b', 'prop_c'], 'my_fish')
>>> r2.prop_a.prop_b.prop_c
'my_fish'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.