2013-08-13 8 views
5

की सुविधा के लिए यहां इकाई परीक्षण के लिए मेरे आवश्यकताएँ हैं:इकाई परीक्षण - लागू करने बराबरी केवल परीक्षण

  1. मैं इकाई मेरी उत्पादन कक्षाओं परीक्षण करना चाहते हैं
  2. मैं परीक्षण कोड और उत्पादन कोड के अलावा इस तरह के अलग करने के लिए चाहते हैं कि मैं केवल उत्पादन कोड जारी कर सकता हूं

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

यहाँ एक User मॉडल के साथ एक सरल उदाहरण है (इंटेलीजे equals और hashCode autoimplemented)

public class User 
{ 
    public long id; 
    public long companyId; 
    public String name; 
    public String email; 
    public long version; 

    @Override 
    public boolean equals(Object o) 
    { 
     if(this == o) return true; 
     if(o == null || getClass() != o.getClass()) return false; 
     User user = (User) o; 
     if(companyId != user.companyId) return false; 
     if(id != user.id) return false; 
     if(version != user.version) return false; 
     if(!email.equals(user.email)) return false; 
     if(!name.equals(user.name)) return false; 
     return true; 
    } 

    @Override 
    public int hashCode() 
    { 
     int result = (int) (id^(id >>> 32)); 
     result = 31 * result + (int) (companyId^(companyId >>> 32)); 
     result = 31 * result + name.hashCode(); 
     result = 31 * result + email.hashCode(); 
     result = 31 * result + (int) (version^(version >>> 32)); 
     return result; 
    } 
} 

यह देखा जा सकता है, equals और hashCode अंतरिक्ष और clutters वर्ग का एक बहुत लेता है।

समस्या का एक समाधान कक्षा, UserTester बनाने के लिए हो सकता है, जिसमें assertUserEquals विधि हो सकती है जिसका उपयोग उदाहरण के बजाय किया जा सकता है। जुनीट का assertEquals

एक और समाधान UserComparator बनाने के लिए हो सकता है। हालांकि, ऐसा लगता है कि जुनीट के पास assertEquals है जो Comparator लेता है।

इस बिंदु पर सर्वोत्तम अभ्यास क्या है?

उत्तर

1

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

public class User { 

    private long id; 
    private String first; 
    private String last; 

    public User(long id, String first, String last) { 
     this.id = id; 
     this.first = first; 
     this.last = last; 
    } 
} 
परीक्षण में बाद में

:

User user1 = new User(1, "John", "Doe"); 
User user2 = new User(1, "John", "Doe"); 
assertReflectionEquals(user1, user2); 

आप Mockito उपयोग कर रहे हैं यह एक ही बात करने के लिए स्वयं के अर्थ है है:

Mockito.verify(userDeleter).delete(Mockito.refEq(user)); 
+0

बस अपनी दस्तावेज़ीकरण की जाँच की। ऐसा लगता है कि आपको 'assertEquals' के बजाय 'assertReflectionEquals' का उपयोग करना चाहिए। ऐसा लगता है कि वें मेरी समस्या का समाधान है। – foens

+0

मेरे बुरा, – Jk1

+0

Ehh देख के लिए धन्यवाद - बस एक छोटी सी समस्या है जो मुझे मेरे सवाल में प्रस्तुत नहीं किया है पाया। मॉकिंग के लिए [mockito] (https://code.google.com/p/mockito/) जैसे ढांचे का उपयोग करने के बारे में क्या? 'सत्यापन (userDeleter) .delete (उपयोगकर्ता)' जैसी विधियों का उपयोग करते समय, यह तर्कों का परीक्षण करने के लिए 'बराबर' का भी उपयोग करता है। क्या आप उस समस्या का कोई समाधान जानते हैं? – foens

0
नहीं

सबसे कारगर लेकिन एक संभव तरीका प्रतिबिंब का उपयोग कर खेतों की तुलना करना है।

public class Foo { 

    int x; 

    Foo(int in){ 
    x = in; 
    } 

    public static void main(String[] args) throws Exception{ 

     Foo o1 = new Foo(1),o2= new Foo(1); 
     boolean allMatch = true; 
     Class<?> c = Class.forName("Foo"); 
     Field[] fields = c.getDeclaredFields(); 

     for(Field f: fields){ 
      allMatch &= f.get(o1)==f.get(o2); 
     } 
    } 
} 
+0

ऐसा लगता है कि Jk1 का जवाब बस अपने विचार का एक बड़े करीने से पैक संस्करण है। क्या यह वाकई धीमा है? – foens

+0

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

0

मैं दो अलग बातें देखें:

  1. कभी कभी यह hashCode & के बराबर होती है ओवरराइड करने के लिए वांछनीय नहीं है। यह अपने कार्यक्रम के व्यवहार को बदल सकते हैं और इसे अपने प्रदर्शन को चोट पहुंचा सकते, Java Overriding hashCode() method has any Performance issue?

  2. देखते हैं, तो वहाँ hashCode &, के बराबर होती है यह मूल्य वस्तु है जैसे, आप ऐसा नहीं होता ओवरराइड करने के लिए कोई ग्राहक आवश्यकता है।आपको ऐसे कोड प्रदान करना चाहिए जो ग्राहक मानदंडों को पूरा करता है, और अधिक नहीं। आपके परीक्षण को डिफ़ॉल्ट ऑब्जेक्ट में मूल कार्यान्वयन से निपटना चाहिए।

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