Python रिटर्न के बजाय MagicMock ऑब्जेक्ट देता है


86

मेरे पास एक अजगर फाइल है a.pyजिसमें दो कक्षाएं हैं Aऔर B

class A(object):
    def method_a(self):
        return "Class A method a"

class B(object):
    def method_b(self):
        a = A()
        print a.method_a()

मैं मजाक method_bमें कक्षा में एकतरफा होना चाहूंगा । इस उद्देश्य के लिए फाइल की सामग्री इस प्रकार है:BAtesta.py

import unittest
import mock
import a


class TestB(unittest.TestCase):

    @mock.patch('a.A')
    def test_method_b(self, mock_a):
        mock_a.method_a.return_value = 'Mocked A'
        b = a.B()
        b.method_b()


if __name__ == '__main__':
    unittest.main()

मुझे Mocked Aआउटपुट में मिलने की उम्मीद है । लेकिन मुझे जो मिलता है वह है:

<MagicMock name='A().method_a()' id='4326621392'>

मैं कहाँ गलत कर रहा हूँ?


1
जब परीक्षण, A()रिटर्न return_valueसे mock_A(एक नियमित रूप से MagicMockआप कुछ और निर्दिष्ट नहीं किया है के रूप में,) है, जो वर्ग का एक उदाहरण नहीं है A। आपको यह निर्धारित करने की आवश्यकता है कि return_valueऐसा कुछ होना चाहिए जिसमें एक परिभाषित हो method_a
जोंशरशेप

3
mock_a.method_a.return_value = 'Mocked A' => mock_a ()। method_a.return_value = 'Mocked A' बेहतर होना चाहिए :)
अली

@AliSAIDOMAR बिल्कुल सही है, यह कॉलिंग से वापसी मूल्य mock_aहै जो विधि के पास होना चाहिए, न कि mock_aस्वयं के लिए।
जोंशरशेप

1
@jonrsharpe आपके विवरण के लिये धन्यवाद। मैंने बस कोशिश की। दोनों mock_a().method_a.return_value = 'Mocked A'और mock_a.return_value.method_a.return_value = 'Mocked A'काम किया। आपकी टिप्पणियों के लिए बहुत बहुत धन्यवाद। क्या आप कृपया इसे आगे बढ़ाएंगे और उत्तर के रूप में डालेंगे?
मेहदी जाफरनिया जहरोमी

@MehdiJafarniaJahromi बहुत बहुत धन्यवाद!
नीकरोस

जवाबों:


96

जब आप @mock.patch('a.A'), आप Aपरीक्षण के तहत कोड में कक्षा की जगह ले रहे हैं mock_a

में B.method_bआप तो सेट a = A()है, जो अब है a = mock_a()- यानी aहै return_valueकी mock_a। जैसा कि आपने यह मान निर्दिष्ट नहीं किया है, यह एक नियमित है MagicMock; यह या तो कॉन्फ़िगर नहीं किया गया है, इसलिए आपको इस MagicMockपर कॉल करते समय डिफ़ॉल्ट प्रतिक्रिया (अभी तक एक और ) मिलती है।

इसके बजाय, आप कॉन्फ़िगर करना चाहते हैं की उचित विधि है, जो या तो आप के रूप में कर सकते हैं के लिए:return_valuemock_a

mock_a().method_a.return_value = 'Mocked A' 
    # ^ note parentheses

या, शायद अधिक स्पष्ट रूप से:

mock_a.return_value.method_a.return_value = 'Mocked A'

आपके कोड ने मामले में काम किया होगा a = A(वर्ग को निर्दिष्ट करना, उदाहरण नहीं बनाना), क्योंकि तब a.method_a()आपकी नकली विधि शुरू हो जाएगी।


4
बहुत बढ़िया। आपने मेरा दिन बना दिया।
विशाल

हाय @jonrsharpe, मैं df.columns के साथ एक पांडा डेटाफ्रेम का उपयोग कर रहा हूँ अगर मेरी स्थिति की जाँच करें । यह कोष्ठक का उपयोग नहीं करता है (यानी, यह कॉल करने योग्य नहीं है)। मैं उस मामले में एक सूची वापस करने के लिए क्या करूं। धन्यवाद!
imsrgadich

@imsrgadich क्या आपको उसके लिए एक नकली की आवश्यकता है? बस उचित डेटाफ़्रेम का निर्माण करें, इसे एक परीक्षण मान के रूप में मानें।
जॉन्सर्शपे

@jonrsharpe हाँ, मैं ऐसा कर सकता था, लेकिन मैं अपनी तथाकथित विधि में df.drop भी कर रहा हूं, जिसे मुझे मुखर करने की आवश्यकता है और उस पर मैं डेटाफ़्रेम को वापस विधि से वापस नहीं कर रहा हूँ। यह एक समस्या पैदा करता है। मुझे एक ऐसा तरीका मिला mock_data.configure_mock(columns='my_column')जिसके इस्तेमाल से यह हल करता है। हालांकि उत्तर के लिए धन्यवाद। (रेफ: bradmontgomery.net/blog/how-world-do-you-mock-name-attribute )
imsrgadich

जब आप एक ही परीक्षा में दो SQLAlchemy मॉडल का मजाक उड़ाते हैं तो यह काम नहीं करता है। पहला एक ठीक काम करता है, लेकिन दूसरा जो आप परिभाषित करते हैं, उसकी परवाह किए बिना एक मैजिकमॉक लौटाएगा।
जूहा अनटाइनन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.