मैं अपने grails एप्लिकेशन के लिए यूनिट परीक्षण लिख रहा हूं, और मुझे एहसास हुआ कि मैं वास्तव में यह सुनिश्चित करने का उचित तरीका नहीं जानता कि कोई वस्तु उचित वस्तु है या नहीं।

उदाहरण के लिए, यह परीक्षण दिया गया है:

void testExampleTest() {
    mockSession.person = new Person(firstName:'John', lastName:'Doe', middleInitial:'E')
    def model = controller.testMethod()
    ...assertions...
}

तथा

def testMethod = {
    Person currPerson = session.getAttribute("person")
    render(view:'view',model:[person:currPerson]
}

मुझे यह कैसे सुनिश्चित करना चाहिए कि जिस व्यक्ति वस्तु को मैंने सत्र में जोड़ा है वह मॉडल में ठीक से पारित किया जा रहा है? क्या यह उपयोग करने के लिए पर्याप्त है

assertEquals( person,model['person'] )

या क्योंकि मैंने ऑब्जेक्ट को स्वयं सत्र में इंजेक्ट किया है, क्या इसका उपयोग करने के लिए और अधिक समझ में आता है

assertEquals( person.firstName, model['person'].firstName )
assertEquals( person.lastName, model['person'].lastName )
assertequals( person.middleName, model['person'].middleName )

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

धन्यवाद

6
Mike Caputo 13 जुलाई 2011, 23:53

8 जवाब

सबसे बढ़िया उत्तर

संपत्ति-दर-संपत्ति तुलना को हर परीक्षण में दोहराया जाना चाहिए - इसलिए यह एक अच्छा पुराना कोड दोहराव है, a परीक्षण गंध का वर्णन XUnitPatterns में किया गया है। बेहतर होगा कि एक उचित equals() हो।

बेशक, आप एक उपयोगिता विधि personEquals() जोड़ सकते हैं या यहां तक ​​कि रनटाइम में Person.equals() को ओवरराइड भी कर सकते हैं। नकली वर्ग के लिए, आपको शायद करना होगा। मैं व्यक्तिगत रूप से छोटे कोड का पालन करता हूं जो संभव होने पर केवल एक assertEquals() है।

4
Victor Sergienko 14 जुलाई 2011, 11:46

अजीब बात है, आज मेरी और एक सहकर्मी के बीच इसी तरह की चर्चा हुई। हमारा निष्कर्ष यह था कि

अधिक श्रमसाध्य विशेषता-दर-विशेषता तुलना का एक लाभ यह है कि यह केवल "नहीं, वे बराबर नहीं हैं" के बजाय एक विशिष्ट अंतर की रिपोर्ट करते हैं, और यह सुविधाजनक हो सकता है।

इसके अलावा, कुछ वर्गों पर हमारा नियंत्रण नहीं था, और उनमें से कुछ के पास समान पद्धति का अभाव था।

हम जांच करना चाहते हैं कि क्या तुलनित्र को लागू करने के लिए प्रतिबिंब का उपयोग करना संभव है, इसलिए कुछ टेडियम को हटा दिया गया है।

2
djna 13 जुलाई 2011, 23:58

मैंने पाया है कि संपत्ति द्वारा संपत्ति करना थोड़ा अधिक विश्वसनीय है और आपको इस पर थोड़ा अधिक बारीक नियंत्रण देता है कि किसी चीज़ की तुलना कैसे की जाती है, नीचे की ओर यह स्थापित करने और बनाए रखने के लिए थोड़ा अधिक काम है

2
Bob The Janitor 14 जुलाई 2011, 00:53

यदि बराबर को ठीक से परिभाषित किया गया है तो आप सही हैं। समस्या यह है कि यदि आपको बराबर परिभाषित किया गया है तो आपको पहले इकाई परीक्षण करना पड़ सकता है (जिसका अर्थ है कि यह जिस तरह से आप उम्मीद करते हैं उससे व्यवहार करता है)।

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

1
Daff 14 जुलाई 2011, 00:00

इस विशेष उदाहरण में, व्यक्तिगत गुणों का परीक्षण करना आपके लिए किसी वस्तु के विशिष्ट उदाहरण की पहचान करने का केवल एक तरीका है, और यह परीक्षण के अर्थ को प्रभावित करता है। आप जिस चीज की विशेष रूप से परवाह करते हैं और जोर देना चाहिए वह यह है कि model['person'] ठीक वही वस्तु है जिसे आपने शुरू में person के रूप में रखा था:

assertSame(person, model['person'])

या हैमक्रेस्ट के साथ, जो समग्र रूप से बहुत अधिक अभिव्यंजक अभिकथन की अनुमति देता है:

assertThat(model['person'], sameInstance(person))
1
Ryan Stewart 14 जुलाई 2011, 00:42

जैसा कि आपने लिखा है, यदि परीक्षण डेटा में उचित समान विधि है, तो आप इसका उपयोग कर सकते हैं। यहां "उचित" का अर्थ है कि यह उन विशेषताओं का परीक्षण करता है जिन्हें आप परीक्षण करना चाहते हैं।

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

assertEqualProperties(person, model['person'], "firstName", "lastName", "middleName");

यह सहायक विधि विशेषताओं तक पहुंचने के लिए प्रतिबिंब का उपयोग करती है (सीधे नहीं, मैं कॉमन्स-बीन्स लाइब्रेरी का आह्वान करता हूं)। ग्रोवी में, निश्चित रूप से एक वाक्यविन्यास है जिसे स्पष्ट प्रतिबिंब की आवश्यकता नहीं है। विधि पहली गैर-बराबर विशेषता को परीक्षण विफलता के रूप में रिपोर्ट करती है।

0
Christian Semrau 14 जुलाई 2011, 00:05

Grails में प्रत्येक वस्तु क्रमबद्ध है, इसलिए आप उनके एक्सएमएल सीरियलाइजेशन का उपयोग करके दोनों की तुलना कर सकते हैं:

public void compareXML(Object a, Object b)
    ByteArrayOutputStream aBaos = new ByteArrayOutputStream();
    XMLEncoder aEncoder = new XMLEncoder(aBaos);
    aEncoder.writeObject(a);
    aEncoder.close();
    String xmlA = baos.toString();

    ByteArrayOutputStream bBaos = new ByteArrayOutputStream();
    XMLEncoder bEncoder = new XMLEncoder(bBaos);
    bEncoder.writeObject(b);
    bEncoder.close();
    String xmlB = bBaos.toString();

    assertEquals(xmlA, xmlB);
}

यदि आप ग्रहण में काम कर रहे हैं, तो आपको सभी अंतरों को दर्शाने वाले दो एक्सएमएल स्ट्रिंग्स की एक महान पाठ्य तुलना मिलेगी।

0
Ryan Gross 14 जुलाई 2011, 00:08

मैं assertSame() का उपयोग करता हूं। फ़ील्ड द्वारा फ़ील्ड की तुलना करना आवश्यक से अधिक काम है - आपने डेटा का मज़ाक उड़ाया, इसलिए केवल यह दावा करें कि नकली मान ठीक से वापस आ गए हैं।

0
Burt Beckwith 14 जुलाई 2011, 00:12