2010-08-05 11 views
11

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

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

उत्तर

6

जब तक आप विशिष्ट डेटाबेस क्रियाओं का परीक्षण नहीं करते हैं (सत्यापित करते हैं कि आप डेटाबेस के लिए क्वेरी या अद्यतन कर सकते हैं) आपके JUnits को वास्तविक डेटाबेस में नहीं लिखा जाना चाहिए। इसके बजाय आपको डेटाबेस कक्षाओं का नकल करना चाहिए। इस तरह आपको वास्तव में डेटाबेस को कनेक्ट और संशोधित नहीं करना है और इसके लिए कोई सफाई की आवश्यकता नहीं है।

आप अपने वर्गों को दो अलग-अलग तरीकों से नकल कर सकते हैं। आप JMock जैसी लाइब्रेरी का उपयोग कर सकते हैं जो आपके लिए सभी निष्पादन और सत्यापन कार्य करेगा। ऐसा करने का मेरा निजी पसंदीदा तरीका निर्भरता इंजेक्शन के साथ है।इस तरह से मैं अपने भंडार इंटरफेस को लागू करने वाले नकली कक्षाएं बना सकता हूं (आप अपने डेटा एक्सेस लेयर के लिए इंटरफेस का उपयोग कर रहे हैं? ;-)) और मैं केवल ज्ञात क्रियाओं/वापसी मानों के साथ आवश्यक विधियों को लागू करता हूं।

//Example repository interface. 
public interface StudentRepository 
{ 
    public List<Student> getAllStudents(); 
} 

//Example mock database class. 
public class MockStudentRepository implements StudentRepository 
{ 
    //This method creates fake but known data. 
    public List<Student> getAllStudents() 
    { 
     List<Student> studentList = new ArrayList<Student>(); 
     studentList.add(new Student(...)); 
     studentList.add(new Student(...)); 
     studentList.add(new Student(...)); 

     return studentList; 
    } 
} 

//Example method to test. 
public int computeAverageAge(StudentRepository aRepository) 
{ 
    List<Student> students = aRepository.GetAllStudents(); 
    int totalAge = 0; 
    for(Student student : students) 
    { 
     totalAge += student.getAge(); 
    } 

    return totalAge/students.size(); 
} 

//Example test method. 
public void testComputeAverageAge() 
{ 
    int expectedAverage = 25; //What the expected answer of your result set is 
    int actualAverage = computeAverageAge(new MockStudentRepository()); 

    AssertEquals(expectedAverage, actualAverage); 
} 
+21

"जब तक आप विशिष्ट डेटाबेस क्रियाओं का परीक्षण नहीं करते हैं (सत्यापित करते हैं कि आप उदाहरण के लिए डेटाबेस को क्वेरी या अपडेट कर सकते हैं) आपके जुनीट को वास्तविक डेटाबेस में नहीं लिखा जाना चाहिए।" इसके बारे में कोई सार्वभौमिक समझौता नहीं है। एक शिविर में, हमारे पास वे लोग हैं जो मानते हैं कि डेटाबेस को मजाक किया जाना चाहिए और दूसरी तरफ हमारे पास उन लोगों का मानना ​​है जो सभी डेटाबेस परीक्षण वास्तविक डेटाबेस के खिलाफ किए जाने चाहिए, आदर्श रूप से उत्पादन डेटाबेस से मेल खाता है। – Behrang

+0

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

+0

जब आपको डेटा पुनर्प्राप्त करने की आवश्यकता होती है तो आप एक कक्षा बनाते हैं और जिस विधि को आपको आवश्यक डेटा लौटने की आवश्यकता होती है उसे लागू करें। यदि आपको डेटा को सहेजने की आवश्यकता है तो आप एक वर्ग बनाते हैं और सहेजते हैं (जिसे भी कहा जाता है) विधि। यह विधि केवल डेटा वैरिएबल (ओं) में स्टोर कर सकती है। यदि आपको सहेजने और पुनर्प्राप्त करने की आवश्यकता है तो उन विधियों को केवल उसी आवृत्ति चर (ओं) से पढ़ने और लिखने की आवश्यकता है। – brainimus

2

मान लें कि आपके पास डेटाबेस तक पहुंच है: दूसरा विकल्प परीक्षण के ठीक पहले डेटाबेस का बैकअप बनाना और परीक्षण के बाद उस बैकअप से पुनर्स्थापित करना है। यह स्वचालित हो सकता है।

+0

हाँ, मेरे पास डेटाबेस तक पहुंच है और यही वह है जो मैं कुछ सहयोगियों से बात करने के बाद भी करने की योजना बना रहा हूं। धन्यवाद जॉन। – Ashish

1

यदि आप स्प्रिंग + जुनीट 4.x का उपयोग कर रहे हैं तो आपको डीबी में कुछ भी डालने की आवश्यकता नहीं है। AbstractTransactionalJUnit4SpringContextTests कक्षा पर देखें।

जुनीट समर्थन के लिए स्प्रिंग दस्तावेज़ देखें।

4

वसंत के यूनिट परीक्षण ढांचे में जेडीबीसी से निपटने के लिए व्यापक क्षमताएं हैं। सामान्य दृष्टिकोण यह है कि इकाई परीक्षण एक लेनदेन में चलता है, और (आपके परीक्षण के बाहर) परीक्षण पूरा होने के बाद लेनदेन वापस लुढ़का जाता है।

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

अधिक पढ़ने के लिए, जेडीबीसी के साथ एकीकरण परीक्षण पर Spring's documentation देखें।

1

यह थोड़ा सा कर्कश है, लेकिन मैं आमतौर पर प्रत्येक टेस्ट विधि निष्पादन से पहले डेटाबेस (या केवल उन तालिकाओं को मिटा देना चाहता हूं) को मिटा देना चाहता हूं। यह काम नहीं करता है क्योंकि मैं कोर्स के अधिक एकीकरण-प्रकार परीक्षण में जाता हूं।

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

आपके मामले में, क्या विशिष्ट आईडी महत्वपूर्ण हैं? क्या आप फ्लाई पर आईडी उत्पन्न कर सकते हैं, शायद यादृच्छिक रूप से, सत्यापित करें कि वे पहले से उपयोग में नहीं हैं, फिर आगे बढ़ें?

4

जुनीट परीक्षण लिखते समय, आप दो विशिष्ट तरीकों को ओवरराइड कर सकते हैं: setUp() और tearDown()। सेटअप() में, आप अपने कोड का परीक्षण करने के लिए आवश्यक सभी चीजें सेट कर सकते हैं ताकि आपको प्रत्येक विशिष्ट परीक्षण मामले में चीजों को सेट न करना पड़े। सभी परीक्षण मामलों के चलने के बाद tearDown() को बुलाया जाता है।

यदि संभव हो, तो आप इसे सेट अप कर सकते हैं ताकि आप सेटअप() विधि में अपना डेटाबेस खोल सकें और फिर इसे परीक्षण से सब कुछ साफ़ कर दें और इसे tearDown() विधि में बंद कर दें। इस प्रकार हमने डेटाबेस के पास सभी परीक्षण किए हैं।

यहाँ एक उदाहरण है:

@Override 
protected void setUp() throws Exception { 
    super.setUp(); 
    db = new WolfToursDbAdapter(mContext); 
    db.open(); 

    //Set up other required state and data 
} 

@Override 
protected void tearDown() throws Exception { 
    super.tearDown(); 
    db.dropTables(); 
    db.close(); 
    db = null; 
} 

//Methods to run all the tests 
1

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

कुछ अच्छी जावा डेटाबेस स्मृति समर्थन में की पेशकश Apache Derby, Java DB (लेकिन यह वास्तव में अपाचे डर्बी के Oracle की स्वाद फिर से है), HyperSQL (बेहतर HSQLDB के रूप में जाना जाता है) और H2 Database Engine हैं। मैंने परीक्षण के लिए इन-मेमोरी मैक डेटाबेस बनाने के लिए व्यक्तिगत रूप से HSQLDB का उपयोग किया है और यह बहुत अच्छा काम करता है, लेकिन मुझे यकीन है कि अन्य समान परिणाम प्रदान करेंगे।

5

DBUnit जैसे कुछ का उपयोग करने के बारे में कैसे?

10

यदि आप वसंत का उपयोग कर रहे हैं, तो आपको अपनी टेस्ट क्लास पर @DirtiesContext एनोटेशन की आवश्यकता है।

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration("/test-context.xml") 
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD) 
public class MyServiceTest { 
    .... 
} 
+2

डर्टीज कॉन्टेक्स्ट स्प्रिंग संदर्भ के मनोरंजन के बारे में है - यह समय लेने वाला ऑपरेशन है, इसलिए यह अच्छा तरीका नहीं है –

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