久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

如何使用 python mock 直接模擬超類?

How do I directly mock a superclass with python mock?(如何使用 python mock 直接模擬超類?)
本文介紹了如何使用 python mock 直接模擬超類?的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學習吧!

問題描述

我正在使用 python 模擬框架進行測試 (http://www.voidspace.org.uk/python/mock/),我想模擬一個超類并專注于測試子類的添加行為.

I am using the python mock framework for testing (http://www.voidspace.org.uk/python/mock/) and I want to mock out a superclass and focus on testing the subclasses' added behavior.

(對于那些感興趣的人,我已經擴展了 pymongo.collection.Collection,我只想測試我添加的行為.我不想為了測試目的而將 mongodb 作為另一個進程運行.)

(For those interested I have extended pymongo.collection.Collection and I want to only test my added behavior. I do not want to have to run mongodb as another process for testing purposes.)

對于本次討論,A 是超類,B 是子類.此外,我定義了直接和間接超類調用,如下所示:

For this discussion, A is the superclass and B is the subclass. Furthermore, I define direct and indirect superclass calls as shown below:

class A(object):
    def method(self):
        ...

    def another_method(self):
        ...

class B(A):
    def direct_superclass_call(self):
        ...
        A.method(self)

    def indirect_superclass_call(self):
        ...
        super(A, self).another_method()

方法#1

A 定義一個名為 MockA 的模擬類,并使用 mock.patch 將其替換為運行時的測試.這處理直接超類調用.然后操縱 B.__bases__ 來處理間接超類調用.(見下文)

Approach #1

Define a mock class for A called MockA and use mock.patch to substitute it for the test at runtime. This handles direct superclass calls. Then manipulate B.__bases__ to handle indirect superclass calls. (see below)

出現的問題是我必須編寫 MockA 并且在某些情況下(如 pymongo.collection.Collection 的情況)這可能涉及很多努力解開所有模擬出來的內部調用.

The issue that arises is that I have to write MockA and in some cases (as in the case for pymongo.collection.Collection) this can involve a lot of work to unravel all of the internal calls to mock out.

所需的方法是以某種方式使用 mock.Mock() 類來及時處理對 mock 的調用,以及在測試中定義的 return_value 或 side_effect.這樣一來,我就可以通過避免 MockA 的定義來做更少的工作.

The desired approach is to somehow use a mock.Mock() class to handle calls on the the mock just in time, as well as defined return_value or side_effect in place in the test. In this manner, I have to do less work by avoiding the definition of MockA.

我遇到的問題是我無法弄清楚如何更改 B.__bases__ 以便可以將 mock.Mock() 的實例作為超類放置(我必須需要以某種方式在這里進行一些直接綁定).到目前為止,我已經確定,super() 檢查 MRO,然后調用定義相關方法的第一個類.我無法弄清楚如何讓超類處理對它的檢查并在遇到模擬類時成功.在這種情況下,似乎沒有使用 __getattr__ .我希望超級認為該方法已在此時定義,然后像往常一樣使用 mock.Mock() 功能.

The issue that I am having is that I cannot figure out how to alter B.__bases__ so that an instance of mock.Mock() can be put in place as a superclass (I must need to somehow do some direct binding here). Thus far I have determined, that super() examines the MRO and then calls the first class that defines the method in question. I cannot figure out how to get a superclass to handle the check to it and succeed if it comes across a mock class. __getattr__ does not seem to be used in this case. I want super to to think that the method is defined at this point and then use the mock.Mock() functionality as usual.

super() 如何發現在 MRO 序列中的類中定義了哪些屬性?有沒有辦法讓我在這里插話并以某種方式讓它動態利用 mock.Mock()?

How does super() discover what attributes are defined within the class in the MRO sequence? And is there a way for me to interject here and to somehow get it to utilize a mock.Mock() on the fly?

import mock

class A(object):
    def __init__(self, value):
        self.value = value      

    def get_value_direct(self):
        return self.value

    def get_value_indirect(self):
        return self.value   

class B(A):
    def __init__(self, value):
        A.__init__(self, value)

    def get_value_direct(self):
        return A.get_value_direct(self)

    def get_value_indirect(self):
        return super(B, self).get_value_indirect()


# approach 1 - use a defined MockA
class MockA(object):
    def __init__(self, value):
        pass

    def get_value_direct(self):
        return 0

    def get_value_indirect(self):
        return 0

B.__bases__ = (MockA, )  # - mock superclass 
with mock.patch('__main__.A', MockA):  
    b2 = B(7)
    print '
Approach 1'
    print 'expected result = 0'
    print 'direct =', b2.get_value_direct()
    print 'indirect =', b2.get_value_indirect()
B.__bases__ = (A, )  # - original superclass 


# approach 2 - use mock module to mock out superclass

# what does XXX need to be below to use mock.Mock()?
#B.__bases__ = (XXX, )
with mock.patch('__main__.A') as mymock:  
    b3 = B(7)
    mymock.get_value_direct.return_value = 0
    mymock.get_value_indirect.return_value = 0
    print '
Approach 2'
    print 'expected result = 0'
    print 'direct =', b3.get_value_direct()
    print 'indirect =', b3.get_value_indirect() # FAILS HERE as the old superclass is called
#B.__bases__ = (A, )  # - original superclass

推薦答案

我按照 kindall 的建議模擬了 super().不幸的是,經過大量的努力,處理復雜的繼承情況變得相當復雜.

I played around with mocking out super() as suggested by kindall. Unfortunately, after a great deal of effort it became quite complicated to handle complex inheritance cases.

經過一些工作,我意識到 super() 在通過 MRO 解析屬性時直接訪問類的 __dict__ (它不執行 getattr 類型的調用).解決方案是擴展一個 mock.MagicMock() 對象并用一個類包裝它來完成此操作.然后可以將包裝的類放在子類的 __bases__ 變量中.

After some work I realized that super() accesses the __dict__ of classes directly when resolving attributes through the MRO (it does not do a getattr type of call). The solution is to extend a mock.MagicMock() object and wrap it with a class to accomplish this. The wrapped class can then be placed in the __bases__ variable of a subclass.

被包裝的對象將目標類的所有已定義屬性反映到包裝類的 __dict__ 中,以便 super() 調用解析為內部 MagicMock() 中正確修補的屬性.

The wrapped object reflects all defined attributes of the target class to the __dict__ of the wrapping class so that super() calls resolve to the properly patched in attributes within the internal MagicMock().

以下代碼是迄今為止我發現的可行的解決方案.請注意,我實際上是在上下文處理程序中實現的.此外,如果從其他模塊導入,則必須注意修補適當的命名空間.

The following code is the solution that I have found to work thus far. Note that I actually implement this within a context handler. Also, care has to be taken to patch in the proper namespaces if importing from other modules.

這是一個說明該方法的簡單示例:

This is a simple example illustrating the approach:

from mock import MagicMock
import inspect 


class _WrappedMagicMock(MagicMock):
    def __init__(self, *args, **kwds):
        object.__setattr__(self, '_mockclass_wrapper', None)
        super(_WrappedMagicMock, self).__init__(*args, **kwds)

    def wrap(self, cls):
        # get defined attribtues of spec class that need to be preset
        base_attrs = dir(type('Dummy', (object,), {}))
        attrs = inspect.getmembers(self._spec_class)
        new_attrs = [a[0] for a in attrs if a[0] not in base_attrs]

        # pre set mocks for attributes in the target mock class
        for name in new_attrs:
            setattr(cls, name, getattr(self, name))

        # eat up any attempts to initialize the target mock class
        setattr(cls, '__init__', lambda *args, **kwds: None)

        object.__setattr__(self, '_mockclass_wrapper', cls)

    def unwrap(self):
        object.__setattr__(self, '_mockclass_wrapper', None)

    def __setattr__(self, name, value):
        super(_WrappedMagicMock, self).__setattr__(name, value)

        # be sure to reflect to changes wrapper class if activated
        if self._mockclass_wrapper is not None:
            setattr(self._mockclass_wrapper, name, value)

    def _get_child_mock(self, **kwds):
        # when created children mocks need only be MagicMocks
        return MagicMock(**kwds)


class A(object):
    x = 1

    def __init__(self, value):
        self.value = value

    def get_value_direct(self):
        return self.value

    def get_value_indirect(self):
        return self.value


class B(A):
    def __init__(self, value):
        super(B, self).__init__(value)

    def f(self):
        return 2

    def get_value_direct(self):
        return A.get_value_direct(self)

    def get_value_indirect(self):
        return super(B, self).get_value_indirect()

# nominal behavior
b = B(3)
assert b.get_value_direct() == 3
assert b.get_value_indirect() == 3
assert b.f() == 2
assert b.x == 1

# using mock class
MockClass = type('MockClassWrapper', (), {})
mock = _WrappedMagicMock(A)
mock.wrap(MockClass)

# patch the mock in
B.__bases__ = (MockClass, )
A = MockClass

# set values within the mock
mock.x = 0
mock.get_value_direct.return_value = 0
mock.get_value_indirect.return_value = 0

# mocked behavior
b = B(7)
assert b.get_value_direct() == 0
assert b.get_value_indirect() == 0
assert b.f() == 2
assert b.x == 0

這篇關于如何使用 python mock 直接模擬超類?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!

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

相關文檔推薦

Python 3 Float Decimal Points/Precision(Python 3 浮點小數點/精度)
Converting Float to Dollars and Cents(將浮點數轉換為美元和美分)
What are some possible calculations with numpy or scipy that can return a NaN?(numpy 或 scipy 有哪些可能的計算可以返回 NaN?)
Python float to ratio(Python浮動比率)
How to manage division of huge numbers in Python?(如何在 Python 中管理大量數字的除法?)
mean from pandas and numpy differ(pandas 和 numpy 的意思不同)
主站蜘蛛池模板: 欧美三级电影在线播放 | 精精久久 | 欧美xxxx日本 | 国产一区二区精品在线 | 国产重口老太伦 | 亚洲一区二区三区四区五区午夜 | 一区二区三区亚洲 | 欧美成人激情 | 欧美激情精品久久久久 | 在线观看国产www | 欧美在线视频一区 | 久久精品国产99国产精品 | 中文字幕黄色大片 | 97精品国产一区二区三区 | 日韩在线看片 | 久色网| 国产一区二区三区欧美 | av超碰| 丁香综合 | 国产小网站 | 在线免费观看a级片 | 久久国产精品久久久久久久久久 | 久久精品国产亚洲夜色av网站 | 久在线| 日韩一区不卡 | 九九国产在线观看 | 午夜丰满少妇一级毛片 | 国产精品精品 | 日韩一二区在线 | a成人| 黄片毛片免费观看 | 婷婷久久综合 | 成人黄色在线视频 | 亚洲二区视频 | 色在线视频网站 | 国产精品免费一区二区三区四区 | 日韩精品1区2区 | 在线91| 黄网站在线播放 | 一级黄色毛片免费 | 欧美精品一区二区在线观看 |