【问题标题】:In Python, how to mock a c extension class?在 Python 中,如何模拟一个 c 扩展类?
【发布时间】:2013-06-20 11:51:42
【问题描述】:

我正在尝试模拟一个在其中使用 c 扩展类的类函数,如下所示,但我得到了TypeError: can't set attributes of built-in/extension type 'y.cExtensionClass'。 code.py 是遗留代码,我真的不想更改它。有什么建议吗?

code.py:

from x.y import cExtensionClass

class CodeClass():

    @staticmethod
    def code_function():
         cExtensionClass().cExtensionFunc()

test.py:

import code
from x.y import cExtensionClass

class test(unittest.TestCase):

    def test_code_function(self)
        with patch.object(cExtensionClass, 'cExtensionFunc') as cExtensionFuncMock:   
            cExtensionFuncMock.return_value = None
            code.CodeClass.code_function()
            cExtensionFuncMock.assert_called_with()

谢谢

【问题讨论】:

    标签: python testing mocking typeerror


    【解决方案1】:

    补丁code.cExtensionClass(不是x.y.cExtensionClass)。 使用import code 而不是from code cExtensionClass

    import unittest
    
    from mock import patch, Mock
    
    import code
    
    class test(unittest.TestCase):
        def test_code_function(self):
            with patch('code.cExtensionClass') as m:
                m.return_value.cExtensionFunc = func = Mock()
                code.CodeClass.code_function()
                func.assert_called_with()
    
        #@patch('code.cExtensionClass')
        #def test_code_function(self, m):
        #    m.return_value.cExtensionFunc = func = Mock()
        #    code.CodeClass.code_function()
        #    func.assert_called_with()
    

    【讨论】:

    • 我现在收到此错误:回溯(最近一次调用最后一次):文件“test.py”,第 196 行,在 test_code_function 中,补丁(code.cExtensionClass)为 m:文件“./ ../../test/mock/mock.py”,第 1551 行,在补丁获取器中,属性 = _get_target(target) 文件“./../../test/mock/mock.py”,第 1389 行,在 _get_target 目标中,属性 = target.rsplit('.', 1) AttributeError: type object 'y.cExtensionClass' has no attribute 'rsplit'
    • 发现问题了,应该用字符串代替类。
    • 你用code.cExtensionClass代替'code.cExtensionClass'吗?
    • 是的,那是我的错误。现在完美运行。非常感谢:)
    • @user1819676,也尝试注释掉装饰器版本。 :)
    【解决方案2】:

    你可以试试forbidden fruit

    禁果

    这个项目旨在帮助你在编写测试时达到天堂,但它 如果在生产代码中使用可能会导致你下地狱。

    它基本上允许您修补用 C 声明的内置对象 通过蟒蛇。就像这样:

    >>> from forbiddenfruit import curse
    >>> def words_of_wisdom(self):
    ...     return self * "blah "
    >>> curse(int, "words_of_wisdom", words_of_wisdom)
    >>> assert (2).words_of_wisdom() == "blah blah "
    

    轰隆隆!就是这样,你的 int 类现在有了 words_of_wisdom 方法。做 你想给一个内置类添加一个类方法吗?没问题,做就行 这个:

    >>> from forbiddenfruit import curse
    >>> def hello(self):
    ...     return "blah"
    >>> curse(str, "hello", classmethod(hello))
    >>> assert str.hello() == "blah"
    

    【讨论】:

      【解决方案3】:

      替换整个 cExtensionClass 对象,而不仅仅是它的单个方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-03-09
        • 1970-01-01
        • 1970-01-01
        • 2015-01-27
        • 2013-12-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多