2010-12-15 15 views

उत्तर

56

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

जब मैं बराबर कॉल की जांच करता हूं, तो मैं यह भी सुनिश्चित करता हूं कि हैशकोड जैसा व्यवहार करना चाहिए।

@Test 
public void testEquals_Symmetric() { 
    Person x = new Person("Foo Bar"); // equals and hashCode check name field value 
    Person y = new Person("Foo Bar"); 
    Assert.assertTrue(x.equals(y) && y.equals(x)); 
    Assert.assertTrue(x.hashCode() == y.hashCode()); 
} 
+9

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

+0

मुझे लगता है कि हमें किसी अन्य विधि का परीक्षण नहीं करना चाहिए, क्योंकि यह परीक्षण केवल हैशकोड के लिए है, इसलिए केवल हैश कोड की तुलना की जानी चाहिए और बाकी कोड को बराबर परीक्षण में लिया जाना चाहिए और अलग-अलग परीक्षण किया जाना चाहिए –

+0

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

1

मुझे नहीं लगता कि एक हैशकोड विधि इकाई-परीक्षण करने की आवश्यकता है। खास तौर पर अगर यह या तो अपने आईडीई या एक HashCodeBuilder (Apache Commons) द्वारा उत्पन्न होता है

+1

कोड पढ़ना संभवतः यह सुनिश्चित करने के लिए सबसे अच्छी जांच है। यानी परीक्षण और त्रुटि से पैतृक मामलों को ढूंढना मुश्किल है। –

4

कई reproduceably यादृच्छिक वस्तुओं (के लाखों लोगों) बनाएं और सेट करने के लिए सभी hashCodes जोड़ सकते हैं और आप की संख्या के रूप में लगभग और कई unqiue मूल्यों को प्राप्त जाँच आईडी उत्पन्न करें। उन्हें पुन: उत्पन्न करने योग्य यादृच्छिक उपयोग एक निश्चित यादृच्छिक बीज का उपयोग करने के लिए।

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

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

+17

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

+1

नीचे वोटों के लिए कोई कारण नहीं दिया गया। एक व्याख्या उपयोगी होगी। –

+2

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

3

hashCode overrided है।

+0

बहुत बहुत धन्यवाद। –

+1

एक परीक्षण उपयोगी है, लेकिन लाखों मूल्यों का परीक्षण करना अधिक उपयोगी होगा और अभी भी एक सेकंड से भी कम समय लेगा। –

5

जब आप सामान्य (हैश कोड की तरह) में एक गणितीय समारोह लिखना है कि आप अपने परीक्षण में कुछ उदाहरण का परीक्षण जब तक आप आश्वस्त समारोह की उम्मीद रूप में काम करता है कि कर रहे हैं: इस तरह। आपके फ़ंक्शन पर कितने उदाहरण हैं।

हैश कोड फ़ंक्शन के लिए मुझे लगता है कि आप कम से कम दो अलग-अलग ऑब्जेक्ट्स का परीक्षण करेंगे, जिन्हें समान हैश कोड के बराबर माना जाता है। जैसा

assertNotSame(obj1, obj2); // don't cheat 
assertEquals(obj1.hashcode(), obj2.hashcode()); 

इसके अलावा आप जांच करनी चाहिए कि दो अलग-अलग मान भिन्न हैश कोड hashcode()return 1; तरह लागू करने से बचने के लिए किया है।

0

हैशकोड के लिए @ डफिमो परीक्षण के अलावा रिफ्लेक्सिव, सममित, और संक्रमणीय होने के अलावा, परीक्षण का एक और तरीका "मैप" के माध्यम से होगा, जहां हैशकोड वास्तव में आसान हो जाते हैं।

@Test 
public void testHashcode() { 
    Person p1 = new Person("Foo Bar"); 
    Person p2 = new Person("Foo Bar"); 
    Map<Person, String> map = new HashMap<>(); 
    map.put(p1, "dummy"); 
    Assert.assertEquals("dummy", map.get(p2)); 
} 
संबंधित मुद्दे