मॉकिटो में पता चला अधूरा स्टबिंग


151

परीक्षण चलाते समय मुझे अपवाद मिल रहे हैं। मैं मॉकिटो का इस्तेमाल मॉकिंग के लिए कर रहा हूं। मॉकिटो लाइब्रेरी द्वारा उल्लिखित संकेत मदद नहीं कर रहे हैं।

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
    -> at com.a.b.DomainTestFactory.myTest(DomainTestFactory.java:355)

    E.g. thenReturn() may be missing.
    Examples of correct stubbing:
        when(mock.isOk()).thenReturn(true);
        when(mock.isOk()).thenThrow(exception);
        doThrow(exception).when(mock).someVoidMethod();
    Hints:
     1. missing thenReturn()
     2. you are trying to stub a final method, you naughty developer!

        at a.b.DomainTestFactory.myTest(DomainTestFactory.java:276)
        ..........

से टेस्ट कोड DomainTestFactory। जब मैं निम्नलिखित परीक्षण चलाता हूं, तो मुझे अपवाद दिखाई देता है।

@Test
public myTest(){
    MyMainModel mainModel =  Mockito.mock(MyMainModel.class);
    Mockito.when(mainModel.getList()).thenReturn(getSomeList()); // Line 355
}

private List<SomeModel> getSomeList() {
    SomeModel model = Mockito.mock(SomeModel.class);
    Mockito.when(model.getName()).thenReturn("SomeName"); // Line 276
    Mockito.when(model.getAddress()).thenReturn("Address");
    return Arrays.asList(model);
}

public class SomeModel extends SomeInputModel{
    protected String address;
    protected List<SomeClass> properties;

    public SomeModel() {
        this.Properties = new java.util.ArrayList<SomeClass>(); 
    }

    public String getAddress() {
        return this.address;
    }

}

public class SomeInputModel{

    public NetworkInputModel() {
        this.Properties = new java.util.ArrayList<SomeClass>(); 
    }

    protected String Name;
    protected List<SomeClass> properties;

    public String getName() {
        return this.Name;
    }

    public void setName(String value) {
        this.Name = value;
    }
}

हाय Mureinik, मैंने पोस्ट संख्याओं के साथ अद्यतन किया है
रॉयल रोज़

जवाबों:


371

आप मज़ाक करने के अंदर मज़ाक कर रहे हैं। आप कॉल कर रहे हैं getSomeList(), जो आपके लिए मॉकिंग समाप्त करने से पहले कुछ मॉकिंग करता है MyMainModel। जब आप ऐसा करते हैं तो मॉकिटो इसे पसंद नहीं करता है।

बदलने के

@Test
public myTest(){
    MyMainModel mainModel =  Mockito.mock(MyMainModel.class);
    Mockito.when(mainModel.getList()).thenReturn(getSomeList()); --> Line 355
}

साथ में

@Test
public myTest(){
    MyMainModel mainModel =  Mockito.mock(MyMainModel.class);
    List<SomeModel> someModelList = getSomeList();
    Mockito.when(mainModel.getList()).thenReturn(someModelList);
}

यह समझने के लिए कि यह समस्या का कारण क्यों है, आपको थोड़ा पता होना चाहिए कि मॉकिटो कैसे काम करता है, और यह भी पता होना चाहिए कि जावा में किस क्रम में अभिव्यक्ति और कथन का मूल्यांकन किया जाता है।

मॉकिटो आपके स्रोत कोड को नहीं पढ़ सकता है, इसलिए यह पता लगाने के लिए कि आप इसे करने के लिए क्या कह रहे हैं, यह स्थिर स्थिति पर बहुत निर्भर करता है। जब आप किसी मॉक ऑब्जेक्ट पर कॉल करते हैं, तो मॉकिटो कॉल की डिटेल्स को इनवोकेशन की आंतरिक सूची में दर्ज करता है। whenविधि सूची से इन आमंत्रण के अंतिम पढ़ता है और इस मंगलाचरण रिकॉर्ड OngoingStubbingवस्तु वापस करती है।

रेखा

Mockito.when(mainModel.getList()).thenReturn(someModelList);

मॉकिटो के साथ निम्नलिखित बातचीत का कारण बनता है:

  • मॉक विधि mainModel.getList()कहा जाता है,
  • स्थैतिक विधि whenकहा जाता है,
  • विधि द्वारा दी गई वस्तु thenReturnपर विधि को कहा जाता है ।OngoingStubbingwhen

thenReturnविधि तो नकली यह माध्यम से प्राप्त निर्देश दे सकते हैं OngoingStubbingविधि के लिए किसी भी उपयुक्त कॉल को संभालने के लिए getListवापसी के लिए विधि someModelList

वास्तव में, जैसा कि मॉकिटो आपके कोड को नहीं देख सकता है, आप निम्न प्रकार से अपना मॉकिंग भी लिख सकते हैं:

mainModel.getList();
Mockito.when((List<SomeModel>)null).thenReturn(someModelList);

यह शैली पढ़ने के लिए कुछ हद तक कम स्पष्ट है, खासकर जब से इस मामले में nullकास्ट किया जाना है, लेकिन यह मॉकिटो के साथ बातचीत का एक ही अनुक्रम उत्पन्न करता है और ऊपर की रेखा के समान परिणाम प्राप्त करेगा।

हालाँकि, रेखा

Mockito.when(mainModel.getList()).thenReturn(getSomeList());

मॉकिटो के साथ निम्नलिखित बातचीत का कारण बनता है:

  1. मॉक विधि mainModel.getList()कहा जाता है,
  2. स्थैतिक विधि whenकहा जाता है,
  3. एक नया mockकी SomeModelबनाई गई है (अंदर getSomeList()),
  4. मॉक विधि model.getName()कहा जाता है,

इस बिंदु पर मॉकिटो भ्रमित हो जाता है। यह सोचा था कि आप मज़ाक कर रहे थे mainModel.getList(), लेकिन अब आप इसे बता रहे हैं कि आप किस model.getName()विधि का मज़ाक करना चाहते हैं । मॉकिटो के लिए, ऐसा लगता है कि आप निम्नलिखित कार्य कर रहे हैं:

when(mainModel.getList());
// ...
when(model.getName()).thenReturn(...);

यह मूर्खतापूर्ण दिखता है Mockitoक्योंकि यह सुनिश्चित नहीं किया जा सकता है कि आप क्या कर रहे हैं mainModel.getList()

ध्यान दें कि हमें thenReturnविधि कॉल करने के लिए नहीं मिला , क्योंकि JVM को विधि को कॉल करने से पहले इस पद्धति के मापदंडों का मूल्यांकन करने की आवश्यकता है। इस मामले में, इसका अर्थ है getSomeList()विधि को कॉल करना ।

आमतौर पर यह स्थैतिक स्थिति पर भरोसा करने के लिए एक बुरा डिजाइन निर्णय है, जैसा कि मॉकिटो करता है, क्योंकि यह उन मामलों को जन्म दे सकता है जहां सिद्धांत का उल्लंघन होता है। हालांकि, मॉकिटो का डिज़ाइन स्पष्ट और अभिव्यंजक मज़ाक के लिए करता है, भले ही वह कभी-कभी विस्मय की ओर ले जाए।

अंत में, मॉकिटो के हाल के संस्करण उपरोक्त त्रुटि संदेश में एक अतिरिक्त रेखा जोड़ते हैं। यह अतिरिक्त रेखा इंगित करती है कि आप इस प्रश्न के समान स्थिति में हो सकते हैं:

3: यदि आप पूरा कर रहे हैं तो 'ifeteturn' निर्देश से पहले आप अंदर एक और नकली के व्यवहार को रोक रहे हैं


क्या इस तथ्य की कोई व्याख्या है? समाधान कार्य करता है। और मुझे समझ में नहीं आता कि 'इन-प्लेस' मॉक क्रिएशन काम क्यों नहीं करता। जब आप नकली बनाते हैं और अन्य नकली के संदर्भ में निर्मित नकली बनाते हैं, तो यह काम करता है।
कैपेसट्रॉन

1
बहुत बढ़िया जवाब, एसओ से प्यार! मुझे यह पता लगाने के लिए उम्र
लगी होगी

4
महान जवाब ल्यूक! सरल शब्दों में बहुत विस्तृत व्याख्या। धन्यवाद।
टॉमाज़ कालकोसीस्की

1
बहुत बढ़िया। मजेदार बात यह है, जब मैं डायरेक्ट मेथड कॉल करता हूं और धीरे-धीरे डिबग करता हूं, तब यह काम करता है। CGLIB $ BO के गुण को सही मान मिलेगा, लेकिन किसी तरह इसमें थोड़ा समय लगता है। जब मैं प्रशिक्षण से पहले प्रत्यक्ष विधि कॉल का उपयोग करता हूं और (जब ...) बंद करता हूं, तो मैं देखता हूं कि मूल्य पहले गलत है, और बाद में सच हो जाता है। जब यह गलत है और प्रशिक्षण शुरू होता है, तो यह अपवाद होता है।
माइकल हेगनर

आपने मेरा दिन बना दिया! यह उस तरह की त्रुटि है जो आपको बहुत समय बर्बाद करती है! मुझे लगा कि यह शुरुआत में कोटलिन से संबंधित कुछ था
ब्रोंक्स

1
org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
E.g. thenReturn() may be missing.

शून्य तरीकों की नकल करने के लिए नीचे आज़माएँ:

//Kotlin Syntax

 Mockito.`when`(voidMethodCall())
           .then {
                Unit //Do Nothing
            }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.