2013-06-24 27 views
2

我試圖嘲笑一個類內部使用c擴展類的類函數,如下所示,但我得到TypeError: can't set attributes of built-in/extension type 'y.cExtensionClass'。 code.py是一個遺留代碼,我真的不想改變它。任何建議?在Python中,如何模擬c擴展類?

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

由於

回答

2

補丁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() 
+0

我現在收到此錯誤: 回溯(最近最後一次通話): 文件 「test.py」,線路196,在test_code_function 與補丁(code.cExtensionClass)爲m: 文件「 ./../../test/mock/mock.py「,第1551行,補丁 getter,attribute = _get_target(target) 文件」./../../test/mock/mock.py「 ,行1389,在_get_target 目標,屬性= target.rsplit('。',1) AttributeError:類型對象'y.cExtensionClass'沒有屬性'rsplit' – user1819676

+0

發現問題,應該使用字符串而不是類。 – user1819676

+0

您是否使用'code.cExtensionClass'而不是'code.cExtensionClass''? – falsetru

0

更換整個cExtensionClass對象,而不是它只是一個單一的方法。

1

你可以嘗試forbidden fruit

禁果

enter image description here

This project aims to help you reach heaven while writing tests, but it may lead you to hell if used on production code.

It basically allows you to patch built-in objects, declared in C through python. Just like this:

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

Boom! That's it, your int class now has the words_of_wisdom method. Do you want to add a classmethod to a built-in class? No problem, just do this:

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