2012-09-21 9 views
59

मैं अपने node.js एप्लिकेशन में डेटाबेस का नकल कैसे करूं, जो इस मामले में mongodb ब्लॉग रीस्ट एपीआई के बैकएंड के रूप में उपयोग करता है?node.js में डेटाबेस का मज़ाक उड़ा रहा है?

निश्चित रूप से, मैं डेटाबेस को एक विशिष्ट testing -डेटाबेस पर सेट कर सकता हूं, लेकिन मैं अभी भी डेटा सहेज सकता हूं और केवल मेरे कोड का परीक्षण नहीं करता, बल्कि डेटाबेस भी, इसलिए मैं वास्तव में यूनिट परीक्षण नहीं कर रहा हूं बल्कि एकीकरण परीक्षण कर रहा हूं।
तो किसी को क्या करना चाहिए? एप्लिकेशन और डीबी के बीच एक मध्यम परत के रूप में डेटाबेस रैपर बनाएं और परीक्षण में डीएएल को प्रतिस्थापित करें?

// app.js 
var express = require('express'); 
    app = express(), 
    mongo = require('mongoskin'), 
    db = mongo.db('localhost:27017/test?auto_reconnect'); 

app.get('/posts/:slug', function(req, res){ 
    db.collection('posts').findOne({slug: req.params.slug}, function (err, post) { 
     res.send(JSON.stringify(post), 200); 
    }); 
}); 

app.listen(3000); 

// test.js 
r = require('requestah')(3000); 
describe("Does some testing", function() { 

    it("Fetches a blogpost by slug", function(done) { 
    r.get("/posts/aslug", function(res) { 
     expect(res.statusCode).to.equal(200); 
     expect(JSON.parse(res.body)["title"]).to.not.equal(null); 
     return done(); 
    }); 

    }); 
)); 

उत्तर

85

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

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

इसलिए, मेरी राय में, सही ढंग से आपके कोड का परीक्षण करने का एकमात्र तरीका यह है कि इसे वास्तविक डेटाबेस के साथ इंटरफ़ेस करना है।

+1

आप जानते हैं, आप एक अच्छा मुद्दा बनाते हैं। जबकि यूनिट परीक्षण एक असाधारण उद्देश्य (यानी अलगाव) प्रदान करता है, आपने एकीकरण परीक्षण के लिए एक मजबूत बिंदु बना दिया है। –

+3

@ माइकलपेरनौड: मुझे क्रिसक के उत्तर द्वारा निर्धारित नियम पसंद है: ** "जो कुछ भी आपके पास नहीं है उसका नकल न करें" **। हालांकि यह विस्तार से नहीं जाता है कि यह एक बुरा विचार क्यों है, यह याद रखना एक आसान नियम है। – slebetman

+1

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

36

वहाँ अंगूठे का एक सामान्य नियम है जब यह मजाक है

कुछ भी आपकी नहीं है नकली नहीं है की बात आती है।

यदि आप डीबी को छिपाना चाहते हैं तो यह एक सारणीबद्ध सेवा परत और उस परत को नकली करना है। फिर सुनिश्चित करें कि आप वास्तविक सेवा परत का एकीकरण परीक्षण करते हैं।

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

+0

निश्चित रूप से आप इसे एक भंडार या गेटवे के पीछे छिपा सकते हैं और अपने परीक्षण संचालित दृष्टिकोण को चलाने और अपने यूनिट परीक्षणों को अलग करने के लिए नकली का उपयोग कर सकते हैं ... क्या मतलब है कि आप परीक्षण के लिए मैक्स का उपयोग नहीं करते हैं? आप अभी भी अपने परीक्षणों में उस मॉक किए गए गेटवे/रिपोजिटरी को रखने वाले हैं, फिर भी किसी इंटरफ़ेस के माध्यम से आपको रीपॉजिटरी में वास्तविक कार्यान्वयन निर्दिष्ट करने के लिए किसी इंटरफ़ेस का उपयोग करें? – PositiveGuy

3

किसी भी भाषा में यूनिट टेस्ट डीबी कोड के लिए मेरा पसंदीदा दृष्टिकोण एक रिपोजिटरी अबास्ट्रक्शन के माध्यम से मोंगो तक पहुंचना है (यहां एक उदाहरण है http://iainjmitchell.com/blog/?p=884)। लागू डीबी विशिष्ट कार्यक्षमता के संदर्भ में कार्यान्वयन अलग-अलग होंगे लेकिन सभी मोंगो कोड को अपने तर्क से हटाकर आप यूनिट टेस्ट की स्थिति में हैं। बस मोंगो रिपोजिटरी कार्यान्वयन को एक स्टब किए गए संस्करण के साथ प्रतिस्थापित करें जो कि मामूली रूप से आसान है। उदाहरण के लिए, बस एक साधारण इन-मेमोरी डिक्शनरी संग्रह में ऑब्जेक्ट्स स्टोर करें।

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

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

+0

लेकिन किसी बिंदु पर आपके असली कार्यान्वयन कोड को वास्तविक डेटा कॉल का संदर्भ देना है। मुझे लगता है कि आप अपने डेटा में इंटरफेस को वास्तविक डेटा लेयर क्वेरी कोड में इंजेक्शन दे रहे हैं? – PositiveGuy

+0

डॉकर का उपयोग करने का प्रयास करें। मैंने परिदृश्य के लिए विशिष्ट परीक्षण डेटा के साथ शुरू किए गए डेटाबेस चलाने वाले कंटेनर चलाने वाले कंटेनर चलाने के लिए डॉकर का उपयोग करके डेटाबेस और पैकेज इंस्टॉल के साथ रात्रिभोज कॉन्फ़िगरेशन समस्याओं का हल किया है। वास्तव में मैं 3 कंटेनरों के ढेर चलाता हूं: एक डीबी के साथ, एक आवेदन कोड के साथ और एक परीक्षण चालक के साथ। यदि आपका डेटा सेट आकार में मध्यम है, तो आप इन परीक्षणों के समानांतर उदाहरणों को भी बढ़ा सकते हैं, जो आपके परीक्षण चक्र को काफी कम करते हैं। – Raidex

32

मैं अब तक चयनित उत्तर या अन्य उत्तरों से सहमत नहीं हूं।

क्या यह शानदार नहीं होगा अगर आप अराजकता से उत्पन्न त्रुटियों को पकड़ सकें और डीबी स्कीमा और आपके कोड में किए गए कई बार गड़बड़ किए गए बदलावों को क्यूए में लाया जाए? मैं शर्त लगाता हूं कि बहुमत हॉक चिल्लाएगा!

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

तो हाँ आपको चाहिए और आपको उस स्कीमा का परीक्षण करना चाहिए जिसे आप जो कुछ भी डीबी इंजन/रनटाइम का उपयोग कर रहे हैं, मेमोरी इंस्टेंस में बहुत हल्के में निर्यात किया जाता है, और साथ ही स्थिर डेटा की बहुत छोटी राशि जोड़ने के साथ आपका पृथक मॉक हो जाता है डीबी।

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

जबकि मैं जवाब देने के लिए अपना सर्वश्रेष्ठ प्रयास करने के प्रयास की सराहना करता हूं, मैं वर्तमान जवाब को कम वोट दूंगा यदि मैं कर सकता हूं लेकिन मैं नया हूं और अभी तक ऐसा करने की क्षमता को सक्षम करने के लिए पर्याप्त प्रतिष्ठा नहीं बनाई है।

उस व्यक्ति के लिए जिसने "किसी भी चीज़ का नकल न करें जो आपके पास नहीं है"। मुझे लगता है कि वह कहने का मतलब था "जो कुछ भी आपके पास नहीं है उसका परीक्षण न करें"। लेकिन आप उन चीज़ों का मज़ाक उड़ाते हैं जिनके पास आपका स्वामित्व नहीं है! क्योंकि वे चीजें ऐसी परीक्षा में नहीं हैं जिन्हें अलग किया जाना चाहिए!

मैं आपके साथ साझा करने की योजना बना रहा हूं और वास्तविक पोस्ट जेएस कोड के साथ भविष्य में इस पोस्ट को भविष्य में अपडेट कर दूंगा!

यह कई परीक्षण संचालित टीमों द्वारा हर समय किया जाता है। आपको बस समझना होगा कि कैसे।

+8

अभी तक कोई अपडेट नहीं है ?? – ChickenWing24

+3

मुझे अपवित्र करना अच्छा लगेगा, लेकिन अगर मैं इस प्रश्न को कम नहीं करता और समाधान प्रदान नहीं करता हूं तो मैं नहीं कर सकता। जब आपको मौका मिलता है तो कृपया अपनी पोस्ट अपडेट करें। – Shanimal

2

मुझे यह दुविधा थी और परीक्षण डीबी के साथ काम करने के लिए चुना गया और परीक्षण शुरू होने पर हर बार इसे साफ़ करें। (सब कुछ कैसे छोड़ें: https://stackoverflow.com/a/25639377/378594)

एनपीएम के साथ आप एक टेस्ट स्क्रिप्ट भी बना सकते हैं जो डीबी फ़ाइल बनाता है और इसे बाद में साफ़ करता है।

+0

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

4

क्या ?! तब कुछ भी नकली क्यों? नकली का उद्देश्य जटिलता और इकाई परीक्षण के अपने कोड को छोड़ना है। यदि आप e2e परीक्षण लिखना चाहते हैं तो डीबी का उपयोग करें।

इकाई परीक्षण के लिए एक परीक्षण डीबी सेटअप/टियरडाउन करने के लिए कोड लिखना तकनीकी ऋण और अविश्वसनीय रूप से असंतुष्ट है।

NPM में नकली पुस्तकालयों के होते हैं:

मोंगो - https://www.npmjs.com/package/mongomock

नेवला - https://www.npmjs.com/package/mockgoose

उन सुविधाओं की जरूरत का समर्थन नहीं करते हैं, तो हाँ आप असली बात उपयोग करना पड़ सकता ।

+1

लॉल "मॉकगोस" शीर्ष 5 सबसे मजेदार एनपीएम पैकेज नाम आईएमओ –

+0

आईएमएचओ अनुकरण की तुलना में नकली करना बेहतर है - https://jsmockito.org/ –

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