जब वास्तविकता बाधा डालती है: Go में हमें मॉक और फिक्स्चर की आवश्यकता क्यों है?
\n\nकल्पना करें कि आप एक फ़ंक्शन का परीक्षण कर रहे हैं जो ईमेल सूचना भेजता है। परीक्षण का हर रन एक वास्तविक ईमेल है जो मेलबॉक्स में जाता है। दस परीक्षणों के बाद आपका मेलबॉक्स भर जाता है, और सहकर्मी स्पैम को कोसते हैं। या इससे भी बुरा: फ़ंक्शन किसी बाहरी API को कॉल करता है जो सशुल्क है या दिन में केवल एक बार काम करता है।
\n\nGo (या Golang, जैसा कि इसे अक्सर कहा जाता है) की दुनिया में, परीक्षण केवल चेकलिस्ट में एक टिक नहीं है। यह विश्वसनीयता की नींव है। लेकिन परीक्षणों को तेज़ और स्वतंत्र बनाने के लिए, हमें कोड को बाहरी दुनिया से अलग करना होगा। यहीं पर mock-ऑब्जेक्ट (मॉक) और फिक्स्चर (fixtures) मंच पर आते हैं।
\n\nइस लेख में, हम समझेंगे कि Go में निर्भरताओं को सही तरीके से कैसे बदलें (मॉक करें) और डेटा कैसे तैयार करें (फिक्स्चर)। आप सीखेंगे कि ऐसे परीक्षण कैसे लिखें जो नेटवर्क, डेटाबेस या दिन के समय के कारण विफल न हों। चलिए शुरू करते हैं!
\n\nGo के संदर्भ में Mock और Fixture क्या हैं?
\n\nMock-ऑब्जेक्ट: जटिल सिस्टम के लिए डुप्लिकेट
\n\nMock-ऑब्जेक्ट सॉफ्टवेयर "स्टब" हैं जो वास्तविक घटकों के व्यवहार का अनुकरण करते हैं। वास्तविक डेटाबेस या HTTP सेवा को कॉल करने के बजाय, हम एक ऐसा ऑब्जेक्ट डालते हैं जो पूर्व-निर्धारित उत्तर लौटाता है।
\n\nGo में मॉक विशेष रूप से महत्वपूर्ण हैं क्योंकि भाषा इंटरफेस के साथ काम करने को प्रोत्साहित करती है। यदि आपका कोड किसी इंटरफेस पर निर्भर करता है, तो आप आसानी से कार्यान्वयन को परीक्षण वाले से बदल सकते हैं।
\n\nफिक्स्चर: मंच तैयार करना
\n\nफिक्स्चर (Fixtures) वे डेटा या स्थितियाँ हैं जो परीक्षण शुरू होने से पहले स्थापित की जानी चाहिए। उदाहरण के लिए, एक अस्थायी डेटाबेस बनाना, उसे परीक्षण रिकॉर्ड से भरना, या फ़ाइल सिस्टम को कॉन्फ़िगर करना।
\n\nमॉक के विपरीत, जो व्यवहार को बदलते हैं, फिक्स्चर वातावरण तैयार करते हैं। वे इस प्रश्न का उत्तर देते हैं: "परीक्षण शुरू करने के लिए क्या तैयार होना चाहिए?"
\n\nGo में मॉक लिखना: सरल से जटिल तक
\n\nसबसे सरल तरीका: इंटरफेस का मैन्युअल कार्यान्वयन
\n\nGo को मॉक बनाने के लिए विशेष लाइब्रेरी की आवश्यकता नहीं है। यदि आपके पास एक इंटरफ़ेस है, तो आप मैन्युअल रूप से इसका परीक्षण कार्यान्वयन लिख सकते हैं। यह छोटे प्रोजेक्ट के लिए आदर्श है।
\n\nमान लीजिए, हमारे पास सूचनाएँ भेजने के लिए एक इंटरफ़ेस है:
\n\npackage notifier\n\ntype Notifier interface {\n Send(to string, message string) error\n}\n\n// वास्तविक कार्यान्वयन (परीक्षण के लिए नहीं)\ntype EmailNotifier struct{}\n\nfunc (e *EmailNotifier) Send(to string, message string) error {\n // वास्तविक ईमेल भेजना\n return nil\n}\n\nपरीक्षण फ़ाइल में, हम एक मॉक बनाते हैं:
\n\npackage notifier\n\nimport "testing"\n\ntype MockNotifier struct {\n Called bool\n LastTo string\n LastMsg string\n}\n\nfunc (m *MockNotifier) Send(to string, msg string) error {\n m.Called = true\n m.LastTo = to\n m.LastMsg = msg\n return nil\n}\n\nfunc TestSendAlert(t *testing.T) {\n mock := &MockNotifier{}\n // फ़ंक्शन में mock का उपयोग करें जो Notifier लेता है\n SendAlert(mock, "user@test.com", "Hello!")\n \n if !mock.Called {\n t.Error("मेथड Send कॉल नहीं हुआ")\n }\n if mock.LastTo != "user@test.com" {\n t.Errorf("गलत प्राप्तकर्ता: %s", mock.LastTo)\n }\n}\n\nलाभ: पूर्ण नियंत्रण, कोई निर्भरता नहीं।
\nनुकसान: जटिल इंटरफेस के लिए बहुत अधिक बॉयलरप्लेट कोड।
testify/mock का उपयोग: शक्तिशाली और सुविधाजनक
\n\nलाइब्रेरी testify Go में मॉक के लिए डी-फैक्टो मानक है। यह तर्कों और कॉलों की संख्या की जाँच के साथ मॉक बनाने के लिए एक लचीला फ्रेमवर्क प्रदान करती है।
स्थापना:
\ngo get github.com/stretchr/testify\n\ntestify/mock के साथ उदाहरण:
\n\npackage user\n\nimport (\n "testing"\n "github.com/stretchr/testify/mock"\n)\n\n// इंटरफ़ेस परिभाषित करें\ntype UserRepository interface {\n GetUser(id int) (string, error)\n}\n\n// मॉक संरचना बनाएं\ntype