2012-08-06 10 views
47

mock के साथ आप एक पठनीय संपत्ति का नकल कैसे करते हैं?नकली के साथ एक पठनीय संपत्ति का नकल कैसे करें?

मैंने कोशिश की:

setattr(obj.__class__, 'property_to_be_mocked', mock.Mock()) 

लेकिन मुद्दा यह है कि यह तो वर्ग ... जो मेरे परीक्षण टूट जाता है की सभी आवृत्तियों के लिए लागू होता है।

क्या आपके पास कोई अन्य विचार है? मैं पूरी वस्तु का नकल नहीं करना चाहता, केवल यह विशिष्ट संपत्ति।

उत्तर

37

असल में, जवाब documentation में (हमेशा की तरह) था, यह सिर्फ इतना है कि जब मैं उनके उदाहरण का पालन करता हूं तो कक्षा के बजाए मैं उदाहरण के लिए पैच को लागू कर रहा था।

class MyClass: 
    @property 
    def last_transaction(self): 
     # an expensive and complicated DB query here 
     pass 

टेस्ट स्वीट में:

def test(): 
    # Make sure you patch on MyClass, not on a MyClass instance, otherwise 
    # you'll get an AttributeError, because mock is using settattr and 
    # last_transaction is a readonly property so there's no setter. 
    with mock.patch(MyClass, 'last_transaction') as mock_last_transaction: 
     mock_last_transaction.__get__ = mock.Mock(return_value=Transaction()) 
     myclass = MyClass() 
     print myclass.last_transaction 
+6

लोगों को अन्य उदाहरण का उपयोग करना चाहिए। 'mock.PropertyMock' ऐसा करने का तरीका है! – vitiral

73

मुझे लगता है कि बेहतर तरीका PropertyMock के रूप में संपत्ति उपहास करने के लिए है, __get__ विधि उपहास करने के लिए के बजाय

तरीके से ऐसा करने के लिए है सीधे।

यह documentation में बताया गया है, unittest.mock.PropertyMock: एक वर्ग पर एक संपत्ति, या अन्य वर्णनकर्ता के रूप में उपयोग करने का इरादा है। PropertyMock__get__ और __set__ विधियों प्रदान करता है ताकि आप इसे प्राप्त होने पर वापसी मूल्य निर्दिष्ट कर सकें।

class MyClass: 
    @property 
    def last_transaction(self): 
     # an expensive and complicated DB query here 
     pass 

def test(unittest.TestCase): 
    with mock.patch('MyClass.last_transaction', new_callable=PropertyMock) as mock_last_transaction: 
     mock_last_transaction.return_value = Transaction() 
     myclass = MyClass() 
     print myclass.last_transaction 
     mock_last_transaction.assert_called_once_with() 
+0

मुझे '@ property' के रूप में सजाए गए क्लास विधि का नकल करना पड़ा। यह उत्तर मेरे लिए काम करता था जब दूसरा उत्तर (और कई अन्य सवालों पर अन्य उत्तरों) नहीं था। – AlanSE

+2

यह वही तरीका है जो इसे किया जाना चाहिए। मेरी इच्छा है कि "स्वीकृत" उत्तर – vitiral

+1

को स्थानांतरित करने का कोई तरीका था, मुझे संदर्भ प्रबंधक कॉल में रिटर्न वैल्यू थोड़ा सा क्लीनर होने के लिए मिलता है: '' mock.patch ('MyClass.last_transaction', new_callable = PropertyMock के साथ , return_value = लेनदेन()): ... '' ' – wodow

3

शायद शैली की लेकिन मामले में आप परीक्षण में सज्जाकार पसंद करते हैं, @ jamescastlefield के answer बात कुछ करने के लिए इस तरह बदला जा सकता है:

class MyClass: 
    @property 
    def last_transaction(self): 
     # an expensive and complicated DB query here 
     pass 

class Test(unittest.TestCase): 
    @mock.patch('MyClass.last_transaction', new_callable=PropertyMock) 
    def test(mock_last_transaction): 
     mock_last_transaction.return_value = Transaction() 
     myclass = MyClass() 
     print myclass.last_transaction 
     mock_last_transaction.assert_called_once_with() 
0

आप तो डॉन

यहाँ है कैसे यह जांचना नहीं चाहता कि मॉक किए गए संपत्ति का उपयोग किया गया था या नहीं, आप इसे return_value के साथ आसानी से पैच कर सकते हैं।

with mock.patch(MyClass, 'last_transaction', Transaction()): 
    ...