2011-03-24 15 views
11

मान लीजिए मैं श्रेणियां होती हैंक्या सी ++ में नकली ऑब्जेक्ट्स हमेशा वर्चुअल तरीके या टेम्पलेट की आवश्यकता होती है?

class Inner { 
    public: 
    void doSomething(); 
}; 

class Outer { 
    public: 
    Outer(Inner *inner); // Dependency injection. 

    void callInner(); 
}; 

उचित इकाई परीक्षण कहता है कि मैं Inner के लिए परीक्षण किया जाना चाहिए। फिर, मेरे पास Outer के लिए परीक्षण होना चाहिए जो वास्तविक Inner नहीं बल्कि MockInner का उपयोग करता है ताकि मैं पूर्ण स्टैक Outer/Inner के बजाय Outer द्वारा जोड़े गए कार्यक्षमता पर इकाई-परीक्षण करूँ।

ऐसा करने के लिए, Googletest एक शुद्ध सार वर्ग (इंटरफेस) इस तरह में Inner मोड़ सुझाव देने के लिए लगता है:

// Introduced merely for the sake of unit-testing. 
struct InnerInterface { 
    void doSomething() = 0; 
}; 

// Used in production. 
class Inner : public InnerInterface { 
    public: 
    /* override */ void doSomething(); 
}; 

// Used in unit-tests. 
class MockInner : public InnerInterface { 
    public: 
    /* override */ void doSomething(); 
}; 

class Outer { 
    public: 
    Outer(Inner *inner); // Dependency injection. 

    void callInner(); 
}; 

तो, उत्पादन कोड में, मैं Outer(new Inner) का प्रयोग करेंगे; परीक्षण में, Outer(new MockInner)

ठीक है। सिद्धांत में अच्छा लगता है, लेकिन जब मैंने इस विचार का उपयोग पूरे कोड में करना शुरू किया, तो मुझे लगता है कि मैं हर फ्रिकिंग क्लास के लिए एक शुद्ध अमूर्त वर्ग बना रहा हूं। यह बहुत सारे बॉयलर-प्लेट टाइपिंग है, भले ही आप अनावश्यक वर्चुअल प्रेषण के कारण मामूली रन-टाइम प्रदर्शन को कमजोर कर सकते हैं।

एक वैकल्पिक दृष्टिकोण के रूप में निम्नलिखित टेम्पलेट का उपयोग करने के लिए है:

class Inner { 
    public: 
    void doSomething(); 
}; 

class MockInner { 
    public: 
    void doSomething(); 
}; 

template<class I> 
class Outer { 
    public: 
    Outer(I *inner); 

    void callInner(); 
}; 

// In production, use 
Outer<Inner> obj; 

// In test, use 
Outer<MockInner> test_obj; 

यह बॉयलर-चढ़ाना और अनावश्यक आभासी प्रेषण से बचा जाता है; लेकिन अब मेरा पूरा कोडबेस फ्रीकिंग हेडर फाइलों में है, जो स्रोत कार्यान्वयन को छिपाना असंभव बनाता है (निराशाजनक टेम्पलेट संकलन त्रुटियों और लंबे समय तक निर्माण के साथ निपटने का उल्लेख नहीं करना)।

क्या वे दो विधियां, वर्चुअल और टेम्पलेट्स हैं, उचित इकाई-परीक्षण करने का एकमात्र तरीका? उचित इकाई परीक्षण करने के बेहतर तरीके हैं?

उचित इकाई परीक्षण द्वारा, मेरा मतलब है प्रत्येक यूनिट-टेस्ट परीक्षण केवल उस इकाई द्वारा पेश की गई कार्यक्षमताएं, लेकिन यूनिट की निर्भरता भी नहीं है।

उत्तर

5

मुझे नहीं लगता कि आपको अभ्यास में अपनी परीक्षण कक्षा की हर निर्भरता को मजाक कर देना चाहिए। यदि यह बनाना, उपयोग करना या समझना जटिल है, तो हाँ। इसके अलावा यदि यह सीधे डीबी, नेटवर्क या फाइल सिस्टम जैसे कुछ अनियंत्रित बाहरी संसाधनों पर निर्भर करता है।

लेकिन यदि इनमें से कोई भी कोई मुद्दा नहीं है, तो आईएमओ केवल इसके उदाहरण का उपयोग करना ठीक है। जैसा कि आप पहले ही इकाई का परीक्षण कर चुके हैं, आप उचित रूप से सुनिश्चित कर सकते हैं कि यह अपेक्षा के अनुसार काम करता है और उच्च स्तरीय यूनिट परीक्षणों में हस्तक्षेप नहीं करता है।

मैं व्यक्तिगत रूप से इकाई परीक्षण परीक्षणों द्वारा कुछ आदर्श सेट अप करने के लिए काम कर रहे यूनिट परीक्षण और सरल, स्वच्छ, रखरखाव योग्य डिजाइन को प्राथमिकता देता हूं।

प्रत्येक यूनिट-टेस्ट परीक्षण केवल उस इकाई द्वारा पेश की गई कार्यक्षमताओं का परीक्षण करता है लेकिन यूनिट की निर्भरता भी नहीं।

एक कार्यक्षमता और एक कार्यक्षमता परीक्षण का उपयोग करते हुए दो बहुत अलग बातें हैं।

+0

मैं व्यक्तिगत रूप से इकाई परीक्षण परीक्षणों द्वारा कुछ आदर्श सेट अप करने के लिए काम कर रहे यूनिट परीक्षण और सरल, स्वच्छ, रखरखाव योग्य डिजाइन को प्राथमिकता देता हूं। मुझे यह प्रतिक्रिया पसंद है --- चीजों को व्यावहारिक रखना। – kirakun

2

मुझे यह भी लगता है कि इनर पर एक उदाहरण का उपयोग सीधे ठीक है। मेरी समस्या बाहरी वस्तुओं का मज़ाक उड़ा रही है जो मेरे कोड का हिस्सा नहीं हैं (स्थिर पुस्तकालयों या डीएलएल, कभी-कभी तृतीय पक्ष के माध्यम से प्रदान की जाती हैं)। मैं एक ही कक्षा के नाम के साथ एक नकली डीएलएल या लाइब्रेरी को फिर से लिखने के इच्छुक हूं, और फिर परीक्षण के लिए अलग-अलग लिंक कर रहा हूं। "आभासी" जोड़ने के लिए बाहरी निर्भरता की हेडर फ़ाइल को संशोधित करना मेरे लिए अस्वीकार्य लगता है। क्या किसी के पास बेहतर समाधान है?