2013-02-21 50 views
16

मैं सी # में अपनी डेटा एक्सेस लेयर इकाई परीक्षण में एक प्रभावी तरीका खोजने की कोशिश कर रहा हूं। मैं प्राथमिक जावा डेवलपर हूं और लगभग 6 महीनों के लिए सी # का उपयोग किया है, अतीत में मैंने एक ज्ञात राज्य डेटाबेस के खिलाफ परीक्षण करने के लिए डीबीयूनीट नामक लाइब्रेरी का उपयोग किया है। मैं एक समान सक्रिय लाइब्रेरी नहीं ढूंढ पा रहा हूं जिसका उपयोग किया जा सकता है, निकटतम nDBUnit लगता है लेकिन यह थोड़ी देर के लिए सक्रिय नहीं है।यूनिट परीक्षण डेटा एक्सेस लेयर के तरीके

सी # में कैसे और क्यों पर कई विरोधाभासी तरीकों की प्रतीत होती है। आदर्श रूप से मैं डेटाबेस से कनेक्ट करने की आवश्यकता के बिना मॉकिंग का उपयोग करके डेटा एक्सेस लेयर का परीक्षण करना चाहता हूं और फिर यूनिट परीक्षण प्रक्रिया को अलग-अलग परीक्षणों में परीक्षण करता हूं।

प्रणाली मैं पर काम कर रहा हूँ में, डेटा का उपयोग परत (इकाई की रूपरेखा के उपयोग के बिना) ADO.net उपयोग करने के लिए एक एसक्यूएल सर्वर पर दुकान प्रक्रियाओं कॉल करने के लिए है।

नीचे एक नमूना कोड है जिसके साथ मुझे काम करना है; मॉकिंग पथ पर जाने के लिए, मुझे एसक्यूएल कॉमांड (आईडीबीकॉमैंड का उपयोग करके) और/या एसक्यूएलकनेक्शन का नकल करने में सक्षम होना होगा।

तो मेरे सवाल का क्या (यदि वहाँ ऐसी बात है) यह करने के लिए सबसे अच्छा तरीका हो रहा है है? अभी तक एकमात्र तरीका प्रोक्सी ऑब्जेक्ट बनाना होगा जो कि कन्स्ट्रक्टर में पास हो जाए, ताकि यह परीक्षण के लिए मॉक किए गए एसक्यूएल * ऑब्जेक्ट्स को वापस कर सके।

मुझे अभी उपलब्ध सभी उपलब्ध सी # नकली पुस्तकालयों को देखने का मौका नहीं मिला है।

public class CustomerRepository : ICustomerRepository 
{ 
    private string connectionString; 

    public CustomerRepository (string connectionString) 
    { 
    this.connectionString = connectionString; 
    } 

    public int Create(Customer customer) 
    { 

    SqlParameter paramOutId = new SqlParameter("@out_id", SqlDbType.Int); 
    paramOutId.Direction = ParameterDirection.Output; 
    List<SqlParameter> sqlParams = new List<SqlParameter>() 
    { 
     paramOutId, 
     new SqlParameter("@name", customer.Name) 
    } 

    SqlConnection connection = GetConnection(); 
    try 
    { 
     SqlCommand command = new SqlCommand("store_proc_name", connection); 

     command.CommandType = CommandType.StoredProcedure; 

     command.Parameters.AddRange(sqlParams.ToArray()); 

     int results = command.ExecuteNonQuery(); 

     return (int) paramOutId.Value; 
    } 
    finally 
    { 
     CloseConnection(connection); 
    } 

    } 

} 

उत्तर

1

मैं एक IDbConnection हो रही है तो आप मूल रूप से है कि से अपने कोड के बाकी क्या कर सकते हैं द्वारा शुरू।

using(IDbConnection conn = factory.GetConnection(connectionstring)) 
{ 
    conn.Open(); 
    using(IDbTransaction trans = conn.BeginTransaction()) 
    { 
     IDbCommand command = conn.CreateCommand(); 
     IDataParameter param = command.CreateParameter(); 
     // Do something with your command 
     trans.Commit(); 
    } 
} 

तो फिर तुम कारखाने, IDbConnection, IDBTransaction नकली कर सकते हैं, और किसी भी अन्य एडीओ आप उन लोगों से बना सकते हैं वस्तुओं। एक मॉक लाइब्रेरी के लिए मैं Moq का उपयोग करता हूं।

+2

पर एक नज़र डालें मुझे लगता है कि यह गलत तरीका है, और भंगुर परीक्षण की ओर जाता है। मेरे तर्क और क्यों एक उदाहरण के लिए मेरा जवाब देखें। –

2

इस परत का काम डेटाबेस को कोड से कनेक्ट करना है। इसे डीबी कनेक्शन और सिंटैक्स के बारे में ज्ञान को समाहित करना है। आमतौर पर डोमेन भाषा को डेटाबेस भाषा में मानचित्रित करता है। मैं यूनिट परीक्षणों के इस भाग को एकीकरण परीक्षण के रूप में देखता हूं, और इस तरह मैं परीक्षण करता हूं कि डेटाबेस स्कीमा वास्तविक या परीक्षण डेटाबेस के बराबर है। विषय here पर अधिक।

+0

धन्यवाद, मुझे लगता है कि मैंने इसमें बहुत मचबूत देखा, मैं मूल रूप से ऐसा करना चाहता था लेकिन सी # में ऐसे पुस्तकालयों की कमी के साथ मैंने एक विकल्प की तलाश शुरू कर दी। – wenic

19

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

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

कुछ संभावित विकल्पों के लिए this question देखें। ऐसा लगता है कि चिह्नित उत्तर वास्तव में IKVM का उपयोग कर सी # में डीबीयूनीट का उपयोग कर समाप्त करना है।

तो, एक्सप्लोर करना जारी रखने के वैकल्पिक विकल्प हो सकते हैं, लेकिन एडीओ कॉल का मज़ाक उड़ाते हुए सिर्फ भंगुर परीक्षणों का कारण बनने जा रहे हैं जो वास्तव में कुछ भी महत्वपूर्ण परीक्षण नहीं करते हैं।

+0

धन्यवाद, मैंने सप्ताहांत में यह एक बेहतर रूप दिया है, मैं मानता हूं कि परीक्षण को वास्तविक डेटाबेस तक पहुंचना चाहिए, हमारी जावा परियोजनाओं के साथ ही यह काम करता है जैसे कि परियोजनाओं में वृद्धि के रूप में टेबल और कॉलम नाम बदल गए हैं। मैंने आईकेएम विधि पर एक नज़र डाली, मैं अन्य डेवलपर्स के प्रबंधन और समझने के लिए कुछ भी जटिल नहीं पेश करूंगा। – wenic

+0

बिल्कुल, यही कारण है कि आपको एक ऐसी सेवा बनाना चाहिए जो एक भंडार/डीएएल का उपयोग करे। आप भंडार का मज़ाक उड़ाते हैं, इसे सेवा में इंजेक्ट करते हैं और उस सेवा का परीक्षण करते हैं। फिर आप अलगाव में सेवा में तर्क का परीक्षण कर रहे हैं। यदि भंडार टूटता है (गलत डेटा देता है), तर्क विफल हो जाएगा और परीक्षण विफल हो जाएगा। लोगों को एक भंडार का मज़ाक उड़ाते हुए और फिर उस भंडार से रिटर्न देने का मजा आता है। आप इसके साथ कुछ भी परीक्षण नहीं कर रहे हैं। – Gaui

0

डेटाएप लेयर का परीक्षण करने के लिए आपको एक और जटिल संरचना की आवश्यकता होगी।

डेटाएप लेयर रिपोजिटरी ऑब्जेक्ट्स से संदर्भ कॉल करेगा। रेपो ऑब्जेक्ट यूनिटऑफवर्क डिजाइन पैटर्न के माध्यम से इकाई फ्रेमवर्क डीबीसेट्स से संदर्भों को कॉल करेगा।

डेटाएप लेयर (टॉप)
|
यूनिटऑफवर्क
|
रिपोजिटरी पैटर्न कक्षाएं
|
ईएफ संदर्भ
|
वास्तविक डेटाबेस

संरचना सेट करने के बाद, आप भंडार कक्षाओं का नकल करेंगे। उदाहरण के लिए, आइटम डीबी में डाले जाएंगे बल्कि मॉक ऑब्जेक्ट पर जाएंगे। बाद में आप आइटम को डालने या नहीं देखने के लिए अपने मॉक ऑब्जेक्ट के खिलाफ जोर देंगे।

कृपया Implementing the Repository and Unit of Work Patterns