Python 修补类实例属性,该属性是另一个类的属性
我正在尝试修补WdmNetworkFailureDetector类的实例属性atom.cache,它是atomtools的属性,atomtools返回和AtomCacheHelper对象。然后我想模拟AtomCacheHelper的query-to-df方法,并返回fixture。我不知道如何正确操作,我尝试了几种方法,大多数方法都会导致相同的属性错误:Python 修补类实例属性,该属性是另一个类的属性,python,unit-testing,mocking,pytest,Python,Unit Testing,Mocking,Pytest,我正在尝试修补WdmNetworkFailureDetector类的实例属性atom.cache,它是atomtools的属性,atomtools返回和AtomCacheHelper对象。然后我想模拟AtomCacheHelper的query-to-df方法,并返回fixture。我不知道如何正确操作,我尝试了几种方法,大多数方法都会导致相同的属性错误: #atomlib/atomtools.py class AtomTools: def __init__(self):
#atomlib/atomtools.py
class AtomTools:
def __init__(self):
self.atomcachehelper = None
@property
def cache(self):
if not self.atomcachehelper:
from atomlib.AtomCacheHelper import AtomCacheHelper
self.atomcachehelper = AtomCacheHelper()
return self.atomcachehelper
# wdm_oms_failures_detector.py
import pandas as pd
from atomlib.atomtools import atomtools as atom
class WdmNetworkFailureDetector(object):
def __init__(self,):
self._cache_helper = atom.cache
def update_wdm_cache_data(self) -> pd.DataFrame:
df_oms = self._cache_helper.query_to_df()
return df_oms
# conftest.py
import pytest
@pytest.fixture(scope='module')
def df_oms():
path = 'some_path.csv'
df_oms = pd.read_csv(path)
return df_oms
# test_wdm_oms_failures_detector.py
from unittest.mock import patch, PropertyMock, call
from wdm_oms_failures_detector WdmNetworkFailureDetector
wnfd = WdmNetworkFailureDetector()
class TestWdmNetworkFailureDetector(object):
def test_get_mol_objects(self):
pass
@patch('wdm_oms_failures_detector.atom.cache')
def test_update_wdm_cache_data(self, mocked_cache, df_oms):
# Setup
mocked_cache.return_value.query_to_df.return_value = df_oms
# Exercise
wnfd.update_wdm_cache_data()
# Verify
mocked_cache.return_value.query_to_df.assert_called_once()
。。。。
埃利夫·夸尔格斯:
#当我们不创建模拟时,无法设置关键字args
#XXXX如果new是一个Mock,我们可以称之为new.configure_Mock(**kwargs)
raise TypeError(“无法将kwargs传递给我们未创建的模拟”)
新建属性=新建
self.temp_original=原件
self.is_local=本地
>setattr(self.target、self.attribute、new_attr)
E AttributeError:无法设置属性
....
self=,exc_info=(,AttributeError(“无法设置属性”),)
定义退出(自我,*exc\U信息):
“”“撤消修补程序。”“”
如果未启动(自启动):
raise RUNTIMERROR('在未启动的修补程序上调用stop')
如果self.is_local和self.temp_original不是默认值:
setattr(self.target、self.attribute、self.temp_-original)
其他:
>delattr(self.target,self.attribute)
E AttributeError:无法删除属性
问题在于,您在补丁之外实例化了测试类,因此缓存帮助器使用真实对象初始化,而稍后对其进行补丁不会改变这一点,因为它已经分配给变量。您必须在修补过程中进行实例化:
测试wdm oms故障检测器.py
....
elif kwargs:
# can't set keyword args when we aren't creating the mock
# XXXX If new is a Mock we could call new.configure_mock(**kwargs)
raise TypeError("Can't pass kwargs to a mock we aren't creating")
new_attr = new
self.temp_original = original
self.is_local = local
> setattr(self.target, self.attribute, new_attr)
E AttributeError: can't set attribute
....
self = <unittest.mock._patch object at 0x000001E9B1618940>, exc_info = (<class 'AttributeError'>, AttributeError("can't set attribute",), <traceback object at 0x000001E9B17EEF48>)
def __exit__(self, *exc_info):
"""Undo the patch."""
if not _is_started(self):
raise RuntimeError('stop called on unstarted patcher')
if self.is_local and self.temp_original is not DEFAULT:
setattr(self.target, self.attribute, self.temp_original)
else:
> delattr(self.target, self.attribute)
E AttributeError: can't delete attribute
from unittest.mock import patch
from wdm_oms_failures_detector import WdmNetworkFailureDetector
class TestWdmNetworkFailureDetector(object):
@patch('wdm_oms_failures_detector.atom.cache')
def test_update_wdm_cache_data(self, mocked_cache, df_oms):
mocked_cache.return_value.query_to_df.return_value = df_oms
wnfd = WdmNetworkFailureDetector() # now the cache helper is set to the mock
wnfd.update_wdm_cache_data()
mocked_cache.query_to_df.assert_called_once()