2009-07-22 17 views
6

वर्तमान उत्पाद जो मैं काम करता हूं वह एक विंडोज सेवा है जो सी ++ में लिखा गया है और आगे बढ़ने के लिए सभी नई कार्यक्षमताओं के लिए यूनिट परीक्षण होंगे। लेकिन यह एक दिलचस्प समस्या पैदा करता है (कम से कम मेरे लिए) हम विभिन्न चीजों के लिए बहुत से Win32 कॉल करते हैं और तदनुसार व्यवहार करते हैं, इसलिए यूनिट परीक्षणों को पूरा करने के लिए विभिन्न प्रकार के आउटपुट का परीक्षण करना अच्छा होगा, न कि वर्तमान प्रणाली राज्य।मॉकिंग और विन 32 एपीआई कॉल

मेरा प्रश्न यह है कि Win32 कॉल के परिणामों का नकल करने का सबसे अच्छा तरीका क्या है? मैंने दो अलग-अलग तरीकों के बारे में सोचा है:

1) सभी Win32 कॉल फ़ंक्शन पॉइंटर्स में उपयोग करें और उन्हें फ़ंक्शंस या क्लास में पास करें (उन्हें कितनी बार मारा जाता है) जो उनका उपयोग करते हैं और नकली पाने के लिए इसका उपयोग करते हैं परिणाम है।

2) हर जगह #ifdef UNITTEST बहुत सारे हैं और यदि यह मेरे स्वयं के विशेष तरीकों को बुला रहा है या सामान्य नहीं है तो कहा जाता है।

क्या मैं यहां आधार से पूरी तरह से बंद हूं, या ज्ञान का मौलिक टुकड़ा खो रहा हूं?

+1

क्या आप UnitTestMessageBox के व्यवहार को संशोधित करने के लिए तर्क की जरूरत है? #ifdef UNITTEST #undef MessageBox #define MessageBox UnitTestMessageBox #endif – Manolete

उत्तर

9

(2) के संबंध में, अधिकांश Win32 फ़ंक्शंस जो स्ट्रिंग पैरामीटर लेते हैं, उनके पास पहले से ही उनके सामान्य रूप को मैक्रो के रूप में परिभाषित किया गया है, उदा। WinUser.h से:

WINUSERAPI 
int 
WINAPI 
MessageBoxA(
    __in_opt HWND hWnd, 
    __in_opt LPCSTR lpText, 
    __in_opt LPCSTR lpCaption, 
    __in UINT uType); 
WINUSERAPI 
int 
WINAPI 
MessageBoxW(
    __in_opt HWND hWnd, 
    __in_opt LPCWSTR lpText, 
    __in_opt LPCWSTR lpCaption, 
    __in UINT uType); 
#ifdef UNICODE 
#define MessageBox MessageBoxW 
#else 
#define MessageBox MessageBoxA 
#endif // !UNICODE 

आप निश्चित रूप से अपनी परियोजना जो एपीआई कार्यों को पुनर्परिभाषित करने के लिए एक शीर्ष लेख जोड़ सकता है आप अनुकरण करना चाहते हैं:

#ifdef UNITTEST 
#undef MessageBox 
#define MessageBox UnitTestMessageBox 
#endif 

नाम को फिर से परिभाषित करने से, आप सशर्त के बहुत सारे बिखरने से बच सकते हैं अपने स्रोत कोड में संकलन।

+0

यह मेरा विचार था कि इसे कैसे किया जाए। यूनिट परीक्षण करने के लिए मैं आपके फ़ंक्शन हस्ताक्षर को बदलने से बचूंगा। –

-1

जब संभव हो, तो Win32 कॉल को संशोधित नहीं करते समय ईवेंट करना बेहतर होगा।

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

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

2

Deviare API हुक का उपयोग करें और सभी एपीआई कॉल को रोकें और अपना यूनिट परीक्षण करें।

4

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

यदि आप हार्डवेयर विकसित नहीं करते हैं तो एक यूनिट परीक्षण में कभी भी हार्डवेयर पहुंच शामिल नहीं होनी चाहिए। यह सिर्फ आपके तर्क कोड का परीक्षण करने के बारे में है।

2

अंत में मैंने वास्तव में एक सी # -श दृष्टिकोण लिया और इंटरफेस बनाया जो मुझे Win32 कॉलों को बाहर निकालने की अनुमति देगा जो मैं उपयोग करना चाहता था।

उदाहरण के लिए मैं एक IRegistryOperations कि RegOpenKey निहित, RegQueryValueEx, RegNotifyChange और कई अन्य मैं उपयोग कर रहा था कहा जाता था। एक वास्तविक व्यक्ति जो वास्तविक फ़ंक्शन में बस कॉल करता है उसे कन्स्ट्रक्टर में बनाया गया था, लेकिन मेरे पास एक कन्स्ट्रक्टर भी था जो इंटरफ़ेस लेता था ताकि मैं डोडी मानों को अनुकरण कर सकूं।

(सुनिश्चित नहीं हैं अगर यह बुरा शिष्टाचार अपने ही सवाल का जवाब देने हालांकि है)

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