2014-08-30 8 views
9

मैं यह कहना चाहता हूं कि एक पायथन कक्षा में एक वर्ग विधि विधि के एक निश्चित सेट के साथ एक और वर्ग विधि को कॉल करती है। मैं मॉक किए गए क्लासमेड को "spec-ed" होना चाहता हूं, इसलिए यह पता लगाता है कि इसे गलत तर्कों के साथ बुलाया गया है या नहीं।अनमॉक क्लास में ऑटोस्पेक के साथ classmethod कैसे पैच करें?

जब मैं patch.object(.., autospec=True, ..) का उपयोग करके कक्षा के पथ को पैच करता हूं, तो वर्ग विधि को NonCallableMagicMock के साथ प्रतिस्थापित किया जाता है और जब मैं इसे कॉल करने का प्रयास करता हूं तो एक त्रुटि उठाता है।

from mock import patch 

class A(object): 

    @classmethod 
    def api_meth(cls): 
     return cls._internal_classmethod(1, 2, 3) 

    @classmethod 
    def _internal_classmethod(cls, n, m, o): 
     return sum(n, m, o) 

with patch.object(A, '_internal_classmethod') as p: 
    print(type(p).__name__) 

with patch.object(A, '_internal_classmethod', autospec=True) as p: 
    print(type(p).__name__) 

उत्पादन का उत्पादन:

MagicMock 
NonCallableMagicMock 

मैं _internal_classmethod के लिए एक युक्ति-एड नकली कैसे प्राप्त कर सकते हैं जब यह करने के लिए वर्ग मज़ाक उड़ाया नहीं है अंतर्गत आता है?

उत्तर

4

autospec के स्थान पर उपयोग करें, और इसे सीधे सेट करें।

with patch.object(A, '_internal_classmethod', spec=A._internal_classmethod) as p: 
    print(type(p).__name__) 

मुझे

MagicMock 
उत्पादन के लिए

देता है।

+6

यह एक गैर-कॉल करने योग्य मैजिकॉक वापस पाने की समस्या को हल करता है, लेकिन दुर्भाग्यवश मॉक किए गए क्लासमेड पर कॉल हस्ताक्षर मिलान को पकड़ने का व्यवहार प्रदान नहीं करता है। यह व्यवहार महत्वपूर्ण है क्योंकि यह विधि के कॉल हस्ताक्षर को बदलकर, कोड को तोड़ने के बावजूद मैक किए गए परीक्षणों के खिलाफ सुरक्षा करता है। मुझे संदेह है कि जिस व्यवहार को मैं ढूंढ रहा हूं वह एक "आंशिक ऑटोस्पेक" है और शायद नकली उस तरह की चीज़ का समर्थन नहीं करता है। – scanny

6

इस समस्या को ठीक करने के लिए एक उत्कृष्ट बग रिपोर्ट (google code link और python bug tracker link) है। जब तक फिक्स शामिल नहीं हो जाता है, तो आप निम्न का प्रयास कर सकते हैं, जो मेरे लिए काम करता है [2.7 पर, हालांकि मुझे लगता है कि यह 3.x में भी काम करेगा]।

def _patched_callable(obj): 
    "Monkeypatch to allow autospec'ed classmethods and staticmethods." 
    # See https://code.google.com/p/mock/issues/detail?id=241 and 
    # http://bugs.python.org/issue23078 for the relevant bugs this 
    # monkeypatch fixes 
    if isinstance(obj, type): 
     return True 
    if getattr(obj, '__call__', None) is not None: 
     return True 
    if (isinstance(obj, (staticmethod, classmethod)) 
     and mock._callable(obj.__func__)): 
     return True 
    return False 
_patched_callable._old_func = mock._callable 
mock._callable = _patched_callable 

monkeypatch के बाद, आप सामान्य रूप से mock.patch का उपयोग करें और static- और वर्ग-तरीकों ठीक से समझौता करने में सक्षम होना चाहिए।

संबंधित मुद्दे