修补类实例属性,该属性是另一个类的属性

2024-04-29 13:34:41 发布

您现在位置:Python中文网/ 问答频道 /正文

#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()

我正在尝试修补WdmNetworkFailureDetector类的实例属性atom.cache,它是atomtools的属性,atomtools返回和AtomCacheHelper对象。然后我想模拟AtomCacheHelper的query-to-df方法,并返回fixture。我不知道如何正确操作,我尝试了几种方法,大多数方法都会导致相同的属性错误:

....
     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

Tags: toimportselfcachedfnewreturnis
1条回答
网友
1楼 · 发布于 2024-04-29 13:34:41

问题在于,您在修补的外部实例化了测试类,因此缓存帮助器用真实对象初始化,而稍后修补不会改变这一点,因为它已经分配给变量。您必须在修补过程中进行实例化:

测试wdm oms故障检测器.py

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()

相关问题 更多 >