pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

修補(bǔ)類會產(chǎn)生“AttributeError:Mock object has no attrib

patching a class yields quot;AttributeError: Mock object has no attributequot; when accessing instance attributes(修補(bǔ)類會產(chǎn)生“AttributeError:Mock object has no attribute;訪問實(shí)例屬性時(shí)) - IT屋-程序員軟件開發(fā)技術(shù)分享
本文介紹了修補(bǔ)類會產(chǎn)生“AttributeError:Mock object has no attribute";訪問實(shí)例屬性時(shí)的處理方法,對大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

問題描述

問題
mock.patchautospec=True 一起使用來修補(bǔ)類不會保留該類實(shí)例的屬性.

The Problem
Using mock.patch with autospec=True to patch a class is not preserving attributes of instances of that class.

詳情
我正在嘗試測試一個(gè)類 Bar,它將類 Foo 的實(shí)例實(shí)例化為名為 fooBar 對象屬性.被測的Bar方法叫做bar;它調(diào)用屬于 BarFoo 實(shí)例的方法 foo.在測試這一點(diǎn)時(shí),我正在模擬 Foo,因?yàn)槲抑幌霚y試 Bar 是否正在訪問正確的 Foo 成員:

The Details
I am trying to test a class Bar that instantiates an instance of class Foo as a Bar object attribute called foo. The Bar method under test is called bar; it calls method foo of the Foo instance belonging to Bar. In testing this, I am mocking Foo, as I only want to test that Bar is accessing the correct Foo member:

import unittest
from mock import patch

class Foo(object):
    def __init__(self):
        self.foo = 'foo'

class Bar(object):
    def __init__(self):
        self.foo = Foo()

    def bar(self):
        return self.foo.foo

class TestBar(unittest.TestCase):
    @patch('foo.Foo', autospec=True)
    def test_patched(self, mock_Foo):
        Bar().bar()

    def test_unpatched(self):
        assert Bar().bar() == 'foo'

類和方法工作得很好(test_unpatched 通過),但是當(dāng)我嘗試使用 autospec=True,我遇到AttributeError: Mock object has no attribute 'foo'"

The classes and methods work just fine (test_unpatched passes), but when I try to Foo in a test case (tested using both nosetests and pytest) using autospec=True, I encounter "AttributeError: Mock object has no attribute 'foo'"

19:39 $ nosetests -sv foo.py
test_patched (foo.TestBar) ... ERROR
test_unpatched (foo.TestBar) ... ok

======================================================================
ERROR: test_patched (foo.TestBar)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 1201, in patched
    return func(*args, **keywargs)
  File "/home/vagrant/dev/constellation/test/foo.py", line 19, in test_patched
    Bar().bar()
  File "/home/vagrant/dev/constellation/test/foo.py", line 14, in bar
    return self.foo.foo
  File "/usr/local/lib/python2.7/dist-packages/mock.py", line 658, in __getattr__
    raise AttributeError("Mock object has no attribute %r" % name)
AttributeError: Mock object has no attribute 'foo'

確實(shí),當(dāng)我打印出 mock_Foo.return_value.__dict__ 時(shí),我可以看到 foo 不在子項(xiàng)或方法列表中:

Indeed, when I print out mock_Foo.return_value.__dict__, I can see that foo is not in the list of children or methods:

{'_mock_call_args': None,
 '_mock_call_args_list': [],
 '_mock_call_count': 0,
 '_mock_called': False,
 '_mock_children': {},
 '_mock_delegate': None,
 '_mock_methods': ['__class__',
                   '__delattr__',
                   '__dict__',
                   '__doc__',
                   '__format__',
                   '__getattribute__',
                   '__hash__',
                   '__init__',
                   '__module__',
                   '__new__',
                   '__reduce__',
                   '__reduce_ex__',
                   '__repr__',
                   '__setattr__',
                   '__sizeof__',
                   '__str__',
                   '__subclasshook__',
                   '__weakref__'],
 '_mock_mock_calls': [],
 '_mock_name': '()',
 '_mock_new_name': '()',
 '_mock_new_parent': <MagicMock name='Foo' spec='Foo' id='38485392'>,
 '_mock_parent': <MagicMock name='Foo' spec='Foo' id='38485392'>,
 '_mock_wraps': None,
 '_spec_class': <class 'foo.Foo'>,
 '_spec_set': None,
 'method_calls': []}

我對 autospec 的理解是,如果為 True,補(bǔ)丁規(guī)范應(yīng)該遞歸應(yīng)用.既然 foo 確實(shí)是 Foo 實(shí)例的一個(gè)屬性,難道不應(yīng)該打補(bǔ)丁嗎?如果沒有,我如何讓 Foo 模擬來保留 Foo 實(shí)例的屬性?

My understanding of autospec is that, if True, the patch specs should apply recursively. Since foo is indeed an attribute of Foo instances, should it not be patched? If not, how do I get the Foo mock to preserve the attributes of Foo instances?

注意:
這是一個(gè)顯示基本問題的簡單示例.實(shí)際上,我正在模擬第三方 module.Class -- consul.Consul -- 我在我擁有的 Consul 包裝類中實(shí)例化了它的客戶端.由于我不維護(hù) consul 模塊,因此我無法修改源代碼以適應(yīng)我的測試(無論如何我都不想這樣做).對于它的價(jià)值,consul.Consul() 返回一個(gè) consul 客戶端,它有一個(gè)屬性 kv - consul.Consul.KV.kv 有一個(gè)方法 get,我將它包裝在我的 Consul 類的實(shí)例方法 get_key 中.打補(bǔ)丁后consul.Consul調(diào)用get失敗,原因是AttributeError: Mock object has no attribute kv.

NOTE:
This is a trivial example that shows the basic problem. In reality, I am mocking a third party module.Class -- consul.Consul -- whose client I instantiate in a Consul wrapper class that I have. As I don't maintain the consul module, I can't modify the source to suit my tests (I wouldn't really want to do that anyway). For what it's worth, consul.Consul() returns a consul client, which has an attribute kv -- an instance of consul.Consul.KV. kv has a method get, which I am wrapping in an instance method get_key in my Consul class. After patching consul.Consul, the call to get fails because of AttributeError: Mock object has no attribute kv.

已檢查資源:

http://mock.readthedocs.org/en/latest/helpers.html#autospeccinghttp://mock.readthedocs.org/en/latest/patch.html

推薦答案

不,autospeccing 不能模擬在原始類的 __init__ 方法(或任何其他方法)中設(shè)置的屬性.它只能模擬出靜態(tài)屬性,所有可以在類中找到的東西.

No, autospeccing cannot mock out attributes set in the __init__ method of the original class (or in any other method). It can only mock out static attributes, everything that can be found on the class.

否則,模擬必須首先創(chuàng)建您嘗試用模擬替換的類的實(shí)例,這不是一個(gè)好主意(想想在實(shí)例化時(shí)創(chuàng)建大量實(shí)際資源的類).

Otherwise, the mock would have to create an instance of the class you tried to replace with a mock in the first place, which is not a good idea (think classes that create a lot of real resources when instantiated).

自動指定的模擬的遞歸性質(zhì)則僅限于那些靜態(tài)屬性;如果 foo 是類屬性,訪問 Foo().foo 將返回該屬性的自動指定模擬.如果你有一個(gè) Spam 類,其 eggs 屬性是 Ham 類型的對象,那么 Spam.eggs 將是 Ham 類的自動指定模擬.

The recursive nature of an auto-specced mock is then limited to those static attributes; if foo is a class attribute, accessing Foo().foo will return an auto-specced mock for that attribute. If you have a class Spam whose eggs attribute is an object of type Ham, then the mock of Spam.eggs will be an auto-specced mock of the Ham class.

您閱讀的文檔 明確em> 涵蓋了這個(gè):

The documentation you read explicitly covers this:

一個(gè)更嚴(yán)重的問題是,實(shí)例屬性通常在 __init__ 方法中創(chuàng)建,而根本不存在于類中.autospec 無法知道任何動態(tài)創(chuàng)建的屬性,并將 api 限制為可見屬性.

A more serious problem is that it is common for instance attributes to be created in the __init__ method and not to exist on the class at all. autospec can’t know about any dynamically created attributes and restricts the api to visible attributes.

您應(yīng)該自己設(shè)置缺少的屬性:

You should just set the missing attributes yourself:

@patch('foo.Foo', autospec=Foo)
def test_patched(self, mock_Foo):
    mock_Foo.return_value.foo = 'foo'
    Bar().bar()

或創(chuàng)建您的 Foo 類的子類用于測試目的,將屬性添加為類屬性:

or create a subclass of your Foo class for testing purposes that adds the attribute as a class attribute:

class TestFoo(foo.Foo):
    foo = 'foo'  # class attribute

@patch('foo.Foo', autospec=TestFoo)
def test_patched(self, mock_Foo):
    Bar().bar()

這篇關(guān)于修補(bǔ)類會產(chǎn)生“AttributeError:Mock object has no attribute";訪問實(shí)例屬性時(shí)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

Python 3 Float Decimal Points/Precision(Python 3 浮點(diǎn)小數(shù)點(diǎn)/精度)
Converting Float to Dollars and Cents(將浮點(diǎn)數(shù)轉(zhuǎn)換為美元和美分)
What are some possible calculations with numpy or scipy that can return a NaN?(numpy 或 scipy 有哪些可能的計(jì)算可以返回 NaN?)
Python float to ratio(Python浮動比率)
How to manage division of huge numbers in Python?(如何在 Python 中管理大量數(shù)字的除法?)
mean from pandas and numpy differ(pandas 和 numpy 的意思不同)
主站蜘蛛池模板: 米顿罗计量泵(科普)——韬铭机械 | MES系统-WMS系统-MES定制开发-制造执行MES解决方案-罗浮云计算 | 注塑_注塑加工_注塑模具_塑胶模具_注塑加工厂家_深圳环科 | 下水道疏通_管道疏通_马桶疏通_附近疏通电话- 立刻通 | 反渗透阻垢剂-缓蚀阻垢剂厂家-循环水处理药剂-山东鲁东环保科技有限公司 | YAGEO国巨电容|贴片电阻|电容价格|三星代理商-深圳市巨优电子有限公司 | 横河变送器-横河压力变送器-EJA变送器-EJA压力变送器-「泉蕴仪表」 | 模具钢_高速钢_不锈钢-万利钢金属材料 | 微波萃取合成仪-电热消解器价格-北京安合美诚科学仪器有限公司 | 万濠投影仪_瑞士TRIMOS高度仪_尼康投影仪V12BDC|量子仪器 | 恒温恒湿试验箱_高低温试验箱_恒温恒湿箱-东莞市高天试验设备有限公司 | 盐水蒸发器,水洗盐设备,冷凝结晶切片机,转鼓切片机,絮凝剂加药系统-无锡瑞司恩机械有限公司 | 上海logo设计| 百度爱采购运营研究社社群-店铺托管-爱采购代运营-良言多米网络公司 | 除甲醛公司-甲醛检测-广西雅居环境科技有限公司 | 金环宇|金环宇电线|金环宇电缆|金环宇电线电缆|深圳市金环宇电线电缆有限公司|金环宇电缆集团 | 生鲜配送系统-蔬菜食材配送管理系统-连锁餐饮订货配送软件-挪挪生鲜供应链管理软件 | 浴室柜-浴室镜厂家-YINAISI · 意大利设计师品牌 | 咿耐斯 |-浙江台州市丰源卫浴有限公司 | 北京浩云律师事务所-企业法律顾问_破产清算等公司法律服务 | 奥因-光触媒除甲醛公司-除甲醛加盟公司十大品牌 | 民用音响-拉杆音响-家用音响-ktv专用音响-万昌科技 | 微信聊天记录恢复_手机短信删除怎么恢复_通讯录恢复软件下载-快易数据恢复 | 沈阳缠绕膜价格_沈阳拉伸膜厂家_沈阳缠绕膜厂家直销 | 生物颗粒燃烧机-生物质燃烧机-热风炉-生物颗粒蒸汽发生器-丽水市久凯能源设备有限公司 | 细石混凝土泵_厂家_价格-烟台九达机械有限公司 | 小型气象站_便携式自动气象站_校园气象站-竞道气象设备网 | 车间除尘设备,VOCs废气处理,工业涂装流水线,伸缩式喷漆房,自动喷砂房,沸石转轮浓缩吸附,机器人喷粉线-山东创杰智慧 | ET3000双钳形接地电阻测试仪_ZSR10A直流_SXJS-IV智能_SX-9000全自动油介质损耗测试仪-上海康登 | CXB船用变压器-JCZ系列制动器-HH101船用铜质开关-上海永上船舶电器厂 | 硫酸亚铁-聚合硫酸铁-除氟除磷剂-复合碳源-污水处理药剂厂家—长隆科技 | 淘气堡_室内儿童乐园_户外无动力儿童游乐设备-高乐迪(北京) | TPE塑胶原料-PPA|杜邦pom工程塑料、PPSU|PCTG材料、PC/PBT价格-悦诚塑胶 | 高防护蠕动泵-多通道灌装系统-高防护蠕动泵-www.bjhuiyufluid.com慧宇伟业(北京)流体设备有限公司 | 硫化罐_蒸汽硫化罐_大型硫化罐-山东鑫泰鑫智能装备有限公司 | 珠海网站建设_响应网站建设_珠海建站公司_珠海网站设计与制作_珠海网讯互联 | 章丘丰源机械有限公司 - 三叶罗茨风机,罗茨鼓风机,罗茨风机 | 上海诺狮景观规划设计有限公司 | 模温机-油温机-电加热导热油炉-工业冷水机「欧诺智能」 | 聚丙烯酰胺_厂家_价格-河南唐达净水材料有限公司 | 合肥废气治理设备_安徽除尘设备_工业废气处理设备厂家-盈凯环保 合肥防火门窗/隔断_合肥防火卷帘门厂家_安徽耐火窗_良万消防设备有限公司 | 粘弹体防腐胶带,聚丙烯防腐胶带-全民塑胶 |