Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 修补类实例属性,该属性是另一个类的属性_Python_Unit Testing_Mocking_Pytest - Fatal编程技术网

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

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

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

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