2013-01-17 29 views
7

निम्नलिखित कोड को देखते हुए मजाक:Mockito ठोस वर्ग

LinkedList list = mock(LinkedList.class); 
    doCallRealMethod().when(list).clear(); 
    list.clear(); 

इस परीक्षण को क्रियान्वित करते हुए, एक NullPointerException LinkedList # में पहली पंक्ति स्पष्ट से फेंक दिया जाता है:

public void clear() { 
    Entry<E> e = header.next; 
    while (e != header) { 
     Entry<E> next = e.next; 
     //Code omitted. 

लेकिन हैडर कर दिया गया है पहले तत्काल:

private transient Entry<E> header = new Entry<E>(null, null, null); 

कुछ एक कृपया नकली सृजन के दौरान क्या हो रहा है समझाओ?

####### अद्यतन। ######

सभी जवाब विशेष रूप से अजय की एक, मैं Objenesis स्रोत कोड में देखा पढ़ सकते हैं और है कि यह छद्म उदाहरण (CGLIB के माध्यम से) बनाने के लिए प्रतिबिंब एपीआई का उपयोग कर रहा है और इसलिए पदानुक्रम में सभी निर्माताओं को दरकिनार करने के बाद यह पता लगाना java.lang.Object तक।

यहाँ नमूना कोड मुद्दा अनुकरण करने के लिए है:

public class ReflectionConstructorTest { 

    @Test 
    public void testAgain() { 

     try { 
      //java.lang.Object default constructor 
      Constructor javaLangObjectConstructor = Object.class 
        .getConstructor((Class[]) null); 
      Constructor mungedConstructor = ReflectionFactory 
        .getReflectionFactory() 
        .newConstructorForSerialization(CustomClient.class, javaLangObjectConstructor); 

      mungedConstructor.setAccessible(true); 

      //Creates new client instance without calling its constructor 
      //Thus "name" is not initialized. 
      Object client = mungedConstructor.newInstance((Object[]) null); 

      //this will print "CustomClient" 
      System.out.println(client.getClass()); 
      //this will print "CustomClient: null". name is null. 
      System.out.println(client.toString()); 

     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 


class CustomClient { 
    private String name; 

    CustomClient() { 
     System.out.println(this.getClass().getSimpleName() + " - Constructor"); 
     this.name = "My Name"; 
    } 

    @Override 
    public String toString() { 
     return this.getClass().getSimpleName() + ": " + name; 
    } 
} 
+0

हमें पूरा स्टैकट्रैक दिखाएं – Archer

उत्तर

5

आपका तर्क निर्दोष है।
मुख्य मुद्दा यह है कि आप वास्तविक LinkedList ऑब्जेक्ट पर काम नहीं कर रहे हैं। यहां दृश्यों के पीछे क्या हो रहा है:

ऑब्जेक्ट जो आपको मॉकिटो mock() द्वारा दिया गया है, वह CG12B लाइब्रेरी से Enhancer ऑब्जेक्ट है।

मेरे लिए यह की तरह java.util.LinkedList$$EnhancerByMockitoWithCGLIB$$cae81a28

कुछ है जो एक प्रॉक्सी की तरह कार्य करता है की तरह, खेतों मूलभूत मूल्यों के लिए सेट के साथ यद्यपि। (शून्य, 0 आदि)

+0

आप सही हैं लेकिन अपवाद वास्तविक वस्तु से फेंक दिया गया है। यहां तक ​​कि डीबगिंग से मैं असली विधि तक पहुंच सकता हूं। मेरा सवाल यह है कि दृश्य के पीछे एक असली "लिंक्डलिस्ट" ऑब्जेक्ट है, तो यह आंतरिक स्थिति भी ठीक होनी चाहिए। – mhshams

+0

कारण है कि आप एक लिंक्डलिस्ट संदर्भ के साथ मॉक ऑब्जेक्ट को संदर्भित करने में सक्षम हैं इसका मतलब है कि मॉक ऑब्जेक्ट लिंक्डलिस्ट का उप-वर्ग है। उम्मीद है की वो मदद करदे। –

+0

भले ही मॉक ऑब्जेक्ट लिंक्डलिस्ट का उप-वर्ग है, इस सबक्लास ऑब्जेक्ट को बनाने के लिए, आपको पैरेंट क्लास ऑब्जेक्ट बनाना होगा। (अभिभावक रचनाकारों को बुलाया जाना चाहिए था) – mhshams

7

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

मॉकिटो लेखक ने खुद कहा है कि वास्तविक चीज़ को बुलाकर शायद ही कभी विरासत कोड का परीक्षण करने के लिए उपयोग किया जाना चाहिए।

आप वास्तविक वस्तु पर जासूसी करने के की जरूरत है (आमंत्रण ट्रैक) तो Mockito भी इस के लिए एक सुविधा है:

List list = new LinkedList(); 
List spy = spy(list); 

जासूस के साथ, आप अभी भी एक विधि ठूंठ सकते हैं यदि आप की जरूरत है। यह मूल रूप से एक नकली की तरह काम करता है, लेकिन नहीं है;)

+1

यह सच है, लेकिन सवाल का जवाब नहीं देता है। इस तथ्य के बाहर, यह करना इतना अच्छा विचार नहीं है, फिर भी हम यह पता लगा सकते हैं कि अपवाद क्यों होता है, है ना? व्लाद स्पष्टीकरण देता है, उसके लिए +1। – Fildor

+0

जैसा कि मैंने उदास किया है: आप केवल मॉकिटो को वास्तविक चीज़ को स्पष्ट रूप से कॉल करने के लिए कह रहे हैं, ऑब्जेक्ट स्वयं को तत्काल नहीं ठहराया जाता है, मॉकिटो इसके नीचे आपके लिए नकली बनाता है। मैंने इसे और स्पष्ट करने के लिए उत्तर संशोधित कर दिया है। मैं अगली बार अधिक स्पष्ट होने की कोशिश करूंगा। – theadam

+1

कोई अपराध नहीं :) बस यह इंगित करना चाहता था कि कभी-कभी, उत्तर का जवाब न देने के उत्तर दिए जाते हैं लेकिन ओपी के कार्यवाही के बारे में पूछताछ करते हैं। और ये कभी-कभी ऐसा करने के लिए डाउनवॉटेड होते हैं। मैंने इसे ओपी को पहले बताए जाने के जवाब में एक अच्छा अभ्यास पाया कि वह ऐसा क्यों नहीं कर रहा है जो वह करता है (और इस प्रकार सवाल का जवाब देता है) और फिर एक विकल्प का सुझाव देता है, अगर मेरे पास कोई प्रस्ताव है। आपके संपादन के बाद, आपके लिए +1 भी। – Fildor

1

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