spock mocking stubbing
मॉकिंग, स्टबिंग और स्पॉक के साथ जासूसी:
स्पॉक फ्रेमवर्क में परिमाणित परीक्षण इसमें विस्तार से बताया गया स्पॉक पर प्रशिक्षण ट्यूटोरियल की श्रृंखला ।
मॉकिंग और स्टबिंग व्यापक यूनिट परीक्षणों के सबसे आवश्यक बिल्डिंग ब्लॉक्स में से एक हैं। मॉकिंग और सबबिंग के लिए समर्थन एक रूपरेखा के लिए केक पर चेरी की तरह है।
JUnit, JBehave, आदि जैसे मौजूदा फ्रेमवर्क के लिए, मोक्स और स्टब्स के लिए समर्थन बॉक्स से बाहर नहीं आता है, इसलिए इसे उपयोग करने के लिए मॉकिटो, पॉवरमॉक, ईज़ीमॉक आदि जैसे थर्ड पार्टी लाइब्रेरी का उपयोग करने के लिए डेवलपर की आवश्यकता होती है। इकाई परीक्षण।
मोक्स और स्टब्स और उनके उपयोग के मामलों को समझने के लिए, आप हमारी श्रृंखला पर एक नज़र डाल सकते हैं मॉकिटो ट्यूटोरियल ।
इस ट्यूटोरियल में, हम स्पोक लाइब्रेरी में इनबिल्ट मॉकिंग और स्टबिंग फीचर्स के बारे में अधिक जानेंगे, जो कि आसान ग्रूवी सिंटैक्स का उपयोग करने में सक्षम होगा और जिससे किसी अन्य 3 को जोड़ने / शामिल करने की आवश्यकता कम हो जाएगी।तृतीयपार्टी पुस्तकालय।
आप हमेशा अपने परीक्षणों में अन्य मॉकिंग फ्रेमवर्क को शामिल कर सकते हैं, क्योंकि सभी वैध जावा कोड वैध ग्रूवी कोड भी हैं।
आप क्या सीखेंगे:
- टेस्ट के तहत आवेदन
- मॉक स्पॉकिंग में
- स्पॉक में ठोकर
- स्पॉक में जासूसी
- निष्कर्ष
- अनुप्रयोग के लिए स्रोत कोड
- अनुशंसित पाठ
टेस्ट के तहत आवेदन
आइए पहले एक नमूना जावा एप्लिकेशन को परिभाषित करें, जिसे हम स्पॉक फ्रेमवर्क में मोक्स और स्टब्स का उपयोग करके परीक्षण करेंगे।
हम एक StudentGradeCalculator ऐप पर काम करेंगे, जो किसी दिए गए छात्र आईडी के लिए एक सार डेटाबेस से कुल स्कोर लेता है और कुल स्कोर के मूल्य के आधार पर ग्रेड असाइनमेंट का एक सरल तर्क है। हम एक डेटाबेस इंटरफ़ेस का उपयोग करेंगे जिसमें छात्र स्कोर और ग्रेड प्राप्त करने और अपडेट करने के लिए कुछ तरीके हैं।
एप्लिकेशन के लिए कोड इस ट्यूटोरियल के अंतिम भाग में उपलब्ध होगा।
मॉक स्पॉकिंग में
वीडियो ट्यूटोरियल
इस खंड में, हम देखेंगे कि Spock फ्रेमवर्क में Mocks को कैसे इंस्टेंट और इनिशियलाइज़ किया जाए और मॉक पर इंटरेक्शन को कैसे वेरिफाई किया जाए यानि कि mocks में कॉल का सत्यापन परीक्षण के तहत विधि की अपेक्षाओं के अनुसार हुआ।
मोक्स के साथ, आपको बहुत सारे सेटअप करने की ज़रूरत नहीं है, लेकिन आप उन इंटरैक्शन को मान्य कर सकते हैं जो परीक्षण के तहत एप्लिकेशन को आपूर्ति की गई नकली वस्तुओं के साथ हुए थे।
मॉक के साथ, आप निम्न कार्य कर सकते हैं:
- मॉक को किन तर्कों के साथ बुलाया गया था?
- चालान आदि की कुल गिनती क्या थी?
- मोक्स के क्रम का पता लगाने।
चलिए स्टूडेंटग्रेडलकुलर का एक सरल उदाहरण देखते हैं, जहाँ हम नकली डेटाबेस कार्यान्वयन ऑब्जेक्ट की आपूर्ति करते हैं और मॉक के साथ बातचीत को मान्य करते हैं। हम सरल उदाहरणों के साथ मॉकिंग सुविधाओं को समझने की कोशिश करेंगे।
कृपया ध्यान दें कि कन्वेंशन द्वारा 'तब' ब्लॉक में सभी इंटरैक्शन वैलिडेशन होने चाहिए।
नीचे परीक्षण के लिए विधि का कोड है (जिसे 'कहा जाएगा' कब अ: ' खंड मैथा)
public String calculateStudentGrade(String studentId) { String grade; // check if grade is already there in database grade = studentDatabase.getStudentGrade(studentId); if(grade!=null && !grade.isEmpty()) { return grade; } List scoreList = studentDatabase.getStudentScores(studentId); Float totalScore = 0F; if(scoreList !=null) totalScore = scoreList.stream().reduce(0F,(a,b)->a+b); if(totalScore > 90) { grade = 'A'; } else if (totalScore > 80) { grade = 'B'; } else { grade = 'C'; } // update the calculated grade in database studentDatabase.updateStudentGrade(studentId, grade); return grade; }
# 1) सटीक तर्कों के साथ बातचीत को मान्य करना: सबसे पहले परस्पर विरोधी तर्कों के साथ बातचीत को मान्य करें। यहां हम उम्मीद करेंगे कि नकली तरीकों को सटीक तर्कों (विधि निष्पादन प्रवाह के अनुसार) के साथ बुलाया जाएगा।
यहाँ ' स्टूडेंटडाटबेस “एक डेटाबेस इंटरफ़ेस का मॉक है जिसके लिए हम इंटरैक्शन को मान्य कर रहे हैं।
def 'illustrate mocks for interaction verification with arguments'() { when: studentReportGenerator.calculateStudentGrade('123'); then: 1*studentDatabase.updateStudentGrade('123','C') 1*studentDatabase.getStudentGrade('123') }
जैसा कि ऊपर दिखाया गया है, हम सटीक तर्कों के साथ मान्य कर रहे हैं, ताकि नकली कार्यान्वयन को बुलाया गया हो। इन तर्कों में कोई भी परिवर्तन परीक्षण विफल हो जाएगा और त्रुटि लॉग उचित कारण दिखाता है।
आइए ग्रेड को बदलने की कोशिश करें updateStudentGrade 'ए' के बजाय वास्तव में 'सी' कहा जाता है और देखें कि परीक्षण निष्पादित होने पर हमें क्या त्रुटि मिलती है।
Too few invocations for: 1*studentDatabase.updateStudentGrade('123','A') (0 invocations) Unmatched invocations (ordered by similarity): 1 * studentDatabase.updateStudentGrade('123', 'C') 1 * studentDatabase.getStudentScores('123')
यह 'बहुत कम इनवोकेशन' जैसी त्रुटि दिखाएगा क्योंकि यह दिए गए तर्कों के साथ मॉक इनवोकेशन नहीं पा सकता है।
#दो) अब देखते हैं कि वास्तविक तर्क मूल्यों की आपूर्ति के बिना मॉक इंटरैक्शन को कैसे मान्य किया जाए, यानी हम जो रुचि रखते हैं, वह सिर्फ इतना जानते हैं कि मॉक को विधि पर लागू किया गया था, लेकिन किन तर्कों के साथ नहीं।
ऐसी वेबसाइटें जो आपको YouTube वीडियो डाउनलोड करने देती हैं
वास्तविक उत्पादन कोड के लिए इकाई परीक्षण लिखते समय इस प्रकार की आवश्यकताएं सबसे आम हैं क्योंकि वास्तविक तर्कों की पहचान करना हमेशा आसान नहीं होता है जो अनिवार्य रूप से परीक्षण के तहत आवेदन के मुख्य व्यवसाय तर्क पर निर्भर करते हैं।
वाक्यविन्यास सरल है, आपको बस एक तर्क के लिए अंडरस्कोर '_' का उपयोग करने की आवश्यकता है जहां वास्तविक मूल्य ज्ञात नहीं है।
उदाहरण के लिए, किसी भी स्ट्रिंग मान के लिए जाँच करने के लिए, आप केवल उल्लेख कर सकते हैं '_ रस्सी जैसी 'परीक्षण में एक तर्क के स्थान पर और इसे किसी भी स्ट्रिंग मूल्य (इसी तरह अन्य आदिम और साथ ही कस्टम डेटा) के लिए पास होना चाहिए।
इसे एक उदाहरण से समझते हैं
def 'illustrate mocks for interaction verification with generic matchers'() { when: studentReportGenerator.calculateStudentGrade('123'); then: 1*studentDatabase.updateStudentGrade(_ as String, _ as String) 1*studentDatabase.getStudentGrade('123') }
यहां ध्यान देने वाली एक महत्वपूर्ण बात यह है कि आप हमेशा तर्क और मैच के लिए क्या तर्क जानते हैं और क्या ज्ञात नहीं है। उदाहरण के लिए, नीचे दिए गए उदाहरण में, हम एक मॉक की बातचीत को वास्तविक तर्कों के साथ और दूसरे को ढीले मिलानकर्ताओं के साथ मान्य कर रहे हैं।
# 3) अंत में, आइए एक परिदृश्य देखें जहां हम मॉक इनवोकेशन के क्रम का पता लगा सकते हैं यानी जब परीक्षण निष्पादित किया जाता है तो किस क्रम को मॉक कहा गया था।
घटनाओं के प्रवाह को मान्य करने के लिए कभी-कभी आवश्यक होता है जब परीक्षण के तहत आवेदन में कई सहयोगी / मॉक शामिल होते हैं और यह समझना और उपयोगी होता है कि विधियों को पूर्व-निर्धारित अनुक्रम में कहा गया था।
def 'illustrate mocks for validating order'() { when: studentReportGenerator.calculateStudentGrade('123'); then: 1*studentDatabase.getStudentGrade('123') then: 1*studentDatabase.updateStudentGrade(_ as String, _ as String) }
यह केवल मॉक अनुक्रम उम्मीदों के क्रम में कई 'तब:' ब्लॉक का उपयोग करके प्राप्त किया जा सकता है। यदि उल्लिखित अनुक्रम आह्वान के वास्तविक आदेश को पूरा नहीं करता है, तो 'गलत मंगलाचरण आदेश' का विवरण देने में एक त्रुटि है।
उदाहरण के लिए, यदि मैं उपरोक्त के क्रम को बदलता हूं तब फिर बयान, परीक्षण निष्पादन नीचे दिखाए गए अनुसार एक त्रुटि फेंक देगा।
Wrong invocation order for: 1*studentDatabase.updateStudentGrade(_ as String, _ as String) (1 invocation) Last invocation: studentDatabase.updateStudentGrade('123', 'C')
स्पॉक में ठोकर
वीडियो ट्यूटोरियल
हमने सभी मॉकिंग के बारे में पता लगाया, अब देखते हैं कि मॉक किए गए ऑब्जेक्ट पर स्टब्स को कैसे परिभाषित किया जाए। स्टबिंग कुछ भी नहीं है, लेकिन परीक्षण के तहत आवेदन के विभिन्न प्रवाह / परिदृश्यों का परीक्षण करने के लिए मॉक इनवोकेशन पर पूर्व-परिभाषित या डिब्बाबंद प्रतिक्रियाएं सेट करना है।
जब इसे बुलाया गया था, तो पूर्व-परिभाषित मूल्य को वापस करने के लिए एक मॉक प्रोग्रामिंग के रूप में सोचें। हम एक ही StudentGradeCalculator ऐप के साथ जारी रहेंगे और विभिन्न परिदृश्यों का परीक्षण करने के लिए डेटाबेस इंटरफ़ेस कॉल को स्टब करेंगे।
एक स्टब एक मॉक की तरह है जो एक तरह से वास्तविक वस्तु के व्यवहार का अनुकरण करता है। आप बस इसे प्रोग्राम्ड मॉक कह सकते हैं।
स्टबिंग सिंटेक्स
स्टबिंग के लिए सिंटैक्स 2 राइट शिफ्ट ऑपरेटर है - अर्थात >> '
किसी भी कॉल पर स्टब सेट करने के लिए, आप इसे निम्नानुसार परिभाषित कर सकते हैं:
StubbedObject.StubbedMethod(//argumentList) >> “Stubbed Response”
आइए अब उदाहरणों के साथ अलग-अलग स्टबिंग परिदृश्यों को समझें।
# 1) वास्तविक मापदंडों के साथ स्टबिंग: यदि तर्कों को पहले से जाना जाता है या यदि आप केवल स्टब सेट करना चाहते हैं, जब आह्वान निर्दिष्ट तर्कों के साथ हो, तो स्टब्स को निर्दिष्ट करने के इस तरीके का उपयोग किया जा सकता है।
def 'illustrate stubs with exact matchers'() { given: studentDatabase.getStudentScores('123') >> (20F, 30F, 50F) when: def grade = studentReportGenerator.calculateStudentGrade('123') then: grade == 'A' }
यहां, आप देख सकते हैं कि स्टब को एक सटीक तर्क के साथ सेट किया गया है, अर्थात इस मामले में स्टूडेंटआईड '123' के रूप में (किसी भी अन्य मूल्य के लिए स्टब को आमंत्रित नहीं किया जाएगा और वहाँ एक डिफ़ॉल्ट प्रतिक्रिया लौटा दी जाएगी)।
# 2) उदार मैचर्स के साथ ठोकर: यदि तर्क ज्ञात नहीं हैं (या महत्वपूर्ण नहीं हैं), तो हम उनका उल्लेख शिथिल रूप से कर सकते हैं जैसा कि हमने मॉक के लिए किया था और वाक्यविन्यास समान है यानी अंडरस्कोर '_'।
def 'illustrate stubs with loose matchers'() { given: studentDatabase.getStudentScores(_ as String) >> (20F, 30F, 10F) when: def grade = studentReportGenerator.calculateStudentGrade('123') then: grade == 'C' }
# 3) आइए एक और त्वरित उदाहरण देखें जहां हमने अपवाद फेंकने के लिए स्टब स्थापित किया है।
परीक्षण के तहत एक आवेदन की त्रुटि से निपटने के तर्क को मान्य करने के लिए ये परिदृश्य बहुत उपयोगी हैं (वास्तविक दुनिया में, वास्तव में सभी अपवाद उत्पन्न करना संभव नहीं है, लेकिन हम जो भी अपवाद चाहते हैं उसे वापस करने के लिए एक सरल ठूंठ स्थापित किया जा सकता है और फिर इसे मुखर कर सकते हैं। तत्कालीन ब्लॉक)।
def 'illustrate stubs with exceptions thrown'() { given: studentDatabase.getStudentScores(_ as String) >> {throw new RuntimeException()} when: studentReportGenerator.calculateStudentGrade('123') then: thrown(RuntimeException.class) }
स्पॉक में जासूसी
जासूस वास्तविक वस्तुओं पर आधारित होते हैं यानी उन्हें इंटरफ़ेस कार्यान्वयन की आवश्यकता है न कि अमूर्त इंटरफ़ेस की। जासूस शक्तिशाली हैं और वे आपको परीक्षण के तहत आवेदन के लिए बुलाए गए वास्तविक तरीकों को प्राप्त करने की अनुमति दे सकते हैं और सत्यापित कर सकते हैं कि तरीकों के लिए क्या तर्क दिए गए थे।
जासूस भी जासूसी वस्तु उदाहरणों पर आंशिक मोक्स को परिभाषित करने की अनुमति देते हैं। यानी मान लीजिए कि आप ऑब्जेक्ट पर कुछ तरीकों के व्यवहार को परिभाषित करना चाहते हैं, तो आप कर सकते हैं और बाकी को कॉल करने की अनुमति दे सकते हैं।
ये आमतौर पर ऐसी स्थिति में उपयोगी होते हैं, जहां इंटरफ़ेस के कुछ तरीके हो सकते हैं जो लागू नहीं होते हैं और कुछ अन्य हैं जो पूरी तरह कार्यात्मक हैं। इसलिए, आप एक डेवलपर के रूप में गैर-कार्यान्वित लोगों को स्टब करने और कार्यात्मक तरीकों के वास्तविक कार्यान्वयन को कॉल करने का विकल्प चुन सकते हैं।
यह ध्यान दिया जाना चाहिए कि, जासूसी वस्तुओं के लिए, जब तक कि स्टब्स को परिभाषित नहीं किया जाता है, तब तक वास्तविक व्यवहार को कॉल करने के लिए डिफ़ॉल्ट व्यवहार होगा। यह कहते हुए कि, जासूसों को अक्सर नहीं बुलाया जाना चाहिए और सभी परिदृश्य कवरेज को मोक्स और स्टब्स और उनके संयोजन का उपयोग करके प्राप्त किया जा सकता है।
आइए उसी उदाहरण का उपयोग करके Spock ढांचे में Spies का उपयोग करके कुछ उदाहरण देखें StudentGradeCalculator (हमने वास्तविक कार्यान्वयन बनाया है स्टूडेंटडाटबेस जो एक इन-मेमोरी कार्यान्वयन का उपयोग कर रहा है हैश मैप वास्तविक तरीकों को कॉल करने और डेटा वापस करने के लिए। कोड ट्यूटोरियल के अंतिम खंड में उपलब्ध होगा):
# 1) स्टब और वास्तविक विधि कॉल के संयोजन का उपयोग करके जासूसी करना
def 'illustrate spies'() { given: StudentDatabase spiedStudentDatabase = Spy(StudentDatabase.class) def studentReportGenerator = new StudentReportGenerator(spiedStudentDatabase) when: def grade = studentReportGenerator.calculateStudentGrade('123') then: grade == 'A' 1*spiedStudentDatabase.getStudentGrade(_ as String) >> 'A' }
उपरोक्त उदाहरण स्पॉक फ्रेमवर्क का उपयोग करके स्पाई बनाने के लिए सिंटैक्स दिखाता है। स्टब को घोषणा समय पर ही परिभाषित किया गया है।
इसके अलावा, जासूसी कॉल को तत्कालीन ब्लॉक में सचित्र के रूप में सत्यापित किया जा सकता है (ढीले तर्क मिलानकर्ता जो किसी भी विशिष्ट तर्क के लिए परिभाषित किया जा सकता है)।
# 2) सभी वास्तविक विधि कॉल का उपयोग कर जासूसी करना
def 'illustrate spies with real method call'() { given: StudentDatabase spiedStudentDatabase = Spy(StudentDatabase.class) def studentReportGenerator = new StudentReportGenerator(spiedStudentDatabase) when: def grade = studentReportGenerator.calculateStudentGrade('123') then: grade == 'C' 1*spiedStudentDatabase.getStudentGrade('123') }
उपर्युक्त उदाहरण में, जैसा कि हमने किसी ठूंठदार व्यवहार का उल्लेख नहीं किया है, सभी कॉल वास्तविक कार्यान्वयन पर जाएंगे।
निष्कर्ष
इस ट्यूटोरियल में, हमने Spock फ्रेमवर्क का उपयोग करके Mock Stub और Spy में इनबिल्ट तकनीकों के बारे में सीखा। स्पॉक इन विशेषताओं को कम बायलरप्लेट कोड के साथ अधिक पठनीय ग्रूवी सिंटैक्स के साथ फ्रेमवर्क के एक भाग के रूप में जोड़कर आसान बनाता है।
मोज़ेक, स्टब्स, और जासूस का उपयोग कवरेज बढ़ाने और परीक्षण के लिए इकाई परीक्षण में बड़े पैमाने पर उपयोग किया जाता है या परीक्षण के लिए आवेदन के मुख्य व्यावसायिक तर्क को मान्य करता है।
अनुप्रयोग के लिए स्रोत कोड
StudentReportGenerator.java - यह परीक्षण के तहत विधि / आवेदन है
package app.studentScores; import java.util.List; public class StudentReportGenerator { public IStudentDatabase studentDatabase; public StudentReportGenerator(IStudentDatabase studentDatabase) { this.studentDatabase = studentDatabase; } public String calculateStudentGrade(String studentId) { String grade; // check if grade is already there in database grade = studentDatabase.getStudentGrade(studentId); if(grade!=null && !grade.isEmpty()) { return grade; } List scoreList = studentDatabase.getStudentScores(studentId); Float totalScore = 0F; if(scoreList !=null) totalScore = scoreList.stream().reduce(0F,(a,b)->a+b); if(totalScore > 90) { grade = 'A'; } else if (totalScore > 80) { grade = 'B'; } else { grade = 'C'; } // update the calculated grade in database studentDatabase.updateStudentGrade(studentId, grade); return grade; } }
IStudentDatabase.java - डेटाबेस इंटरफ़ेस
package app.studentScores; import java.util.List; public interface IStudentDatabase { List getStudentScores(String studentId); void updateStudentGrade(String studentId, String grade); String getStudentGrade(String studentId); }
StudentDatabase.java - IStudentDatabase.java इंटरफ़ेस का इनमेमोरी कार्यान्वयन
package app.studentScores; import java.util.*; public class StudentDatabase implements IStudentDatabase { private Map scoreMap; private Map gradeMap; public StudentDatabase() { this.scoreMap = new HashMap(); this.gradeMap = new HashMap(); scoreMap.put('123', Arrays.asList(40F, 30F, 30F)); scoreMap.put('456', Arrays.asList(10F, 10F, 30F)); gradeMap.put('123', 'C'); gradeMap.put('456', 'A'); } @Override public List getStudentScores(String studentId) { return scoreMap.get(studentId); } @Override public void updateStudentGrade(String studentId, String grade) { gradeMap.put(studentId,grade); } @Override public String getStudentGrade(String studentId) { return gradeMap.get(studentId); } }
हमारे आगामी ट्यूटोरियल में, हम देखेंगे कि अन्य परीक्षण ढांचे और प्रौद्योगिकियों के साथ स्पॉक फ्रेमवर्क को कैसे एकीकृत किया जाए।
PREV ट्यूटोरियल | अगले ट्यूटोरियल
अनुशंसित पाठ
- स्पॉक फ्रेमवर्क के साथ यूनिट टेस्ट लिखना
- उत्तर के साथ स्पॉक साक्षात्कार प्रश्न (सर्वाधिक लोकप्रिय)
- सेलेनियम के साथ एकीकरण और कार्यात्मक परीक्षण के लिए स्पॉक
- स्पॉक फ्रेमवर्क के साथ डेटा-संचालित या परिमितित परीक्षण
- स्पॉक ट्यूटोरियल: स्पॉक एंड ग्रूवी के साथ परीक्षण
- सर्वश्रेष्ठ मुफ्त सी # ट्यूटोरियल श्रृंखला: शुरुआती के लिए अंतिम सी # गाइड
- एचपी लोडरनर ट्यूटोरियल के साथ लोड परीक्षण
- C ++ में दिनांक और समय कार्य उदाहरण के साथ