पहला कॉल विफल हो जाता है, दूसरा कॉल सफल होता है


119

मैं नीचे (सरलीकृत) कोड का परीक्षण करने के लिए मॉकिटो का उपयोग करना चाहता हूं। मैं नहीं जानता कि पहली बार असफल होने के लिए मॉकिटो को कैसे बताया जाए, फिर दूसरी बार सफल हुआ।

for(int i = 1; i < 3; i++) {
  String ret = myMock.doTheCall();

  if("Success".equals(ret)) {
    log.write("success");
  } else if ( i < 3 ) {
    log.write("failed, but I'll try again. attempt: " + i);
  } else {
    throw new FailedThreeTimesException();
  }
}

मैं सफलता परीक्षण के साथ सेटअप कर सकता हूं:

Mockito.when(myMock).doTheCall().thenReturn("Success");

और विफलता परीक्षण के साथ:

Mockito.when(myMock).doTheCall().thenReturn("you failed");

लेकिन मैं कैसे परीक्षण कर सकता हूं कि अगर यह एक बार (या दो बार) विफल रहता है तो सफल होता है, यह ठीक है?

जवाबों:


250

से डॉक्स :

कभी-कभी हमें एक ही विधि कॉल के लिए अलग-अलग रिटर्न वैल्यू / अपवाद के साथ स्टब करने की आवश्यकता होती है। विशिष्ट उपयोग का मामला पुनरावृत्तियों का मजाक उड़ा सकता है। मॉकिटो के मूल संस्करण में सरल मॉकिंग को बढ़ावा देने के लिए यह सुविधा नहीं थी। उदाहरण के लिए, पुनरावृत्तियों के बजाय कोई Iterable या बस संग्रहों का उपयोग कर सकता है। वे स्टबिंग के प्राकृतिक तरीके प्रदान करते हैं (जैसे वास्तविक संग्रह का उपयोग करके)। हालांकि दुर्लभ परिदृश्यों में लगातार कॉल करना उपयोगी हो सकता है, हालांकि:

when(mock.someMethod("some arg"))
   .thenThrow(new RuntimeException())
  .thenReturn("foo");

//First call: throws runtime exception:
mock.someMethod("some arg");

//Second call: prints "foo"
System.out.println(mock.someMethod("some arg"));

तो आपके मामले में, आप चाहते हैं:

when(myMock.doTheCall())
   .thenReturn("You failed")
   .thenReturn("Success");

25
इसने मुझे अपने परिदृश्य के लिए सही दिशा (धन्यवाद) में बताया जो शून्य तरीकों से काम कर रहा था - उस उदाहरण में आपको वैकल्पिक शैली का उपयोग करने की आवश्यकता है ...doThrow(new RuntimeException()).doNothing().when(myMock).doTheCall();
haggisandchips

38

जो आप चाहते हैं उसे लिखने का सबसे छोटा तरीका

when(myMock.doTheCall()).thenReturn("Success", "you failed");

जब आप thenReturnइस तरह से म्यूटेंट तर्कों की आपूर्ति करते हैं, तो प्रत्येक तर्क का उपयोग एक बार में किया जाएगा, बहुत अंतिम तर्क को छोड़कर, जिसका उपयोग कई बार आवश्यक के रूप में किया जाता है। उदाहरण के लिए, इस मामले में, यदि आप 4 बार कॉल करते हैं, तो आपको "सफलता", "आप विफल", "आप विफल", "आप विफल" हो जाएंगे।


22

चूँकि इस से संबंधित टिप्पणी को पढ़ना मुश्किल है, इसलिए मैं एक प्रारूपित उत्तर जोड़ूंगा।

यदि आप एक ऐसे voidकार्य को करने की कोशिश कर रहे हैं जो केवल एक अपवाद को फेंकता है, उसके बाद कोई व्यवहार नहीं करता है, तो आप कुछ ऐसा करेंगे:

Mockito.doThrow(new Exception("MESSAGE"))
            .doNothing()
            .when(mockService).method(eq());

4

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

ईजी (हालांकि एक दूर के एक):

import org.mockito.stubbing.Stubber;

Stubber stubber = doThrow(new Exception("Exception!"));
for (int i=0; i<10; i++) {
    if (i%2 == 0) {
        stubber.doNothing();
    } else {
        stubber.doThrow(new Exception("Exception"));
    }
}
stubber.when(myMockObject).someMethod(anyString());

मैं वास्तव में इस स्टबर के बारे में नहीं जानता था और इसे उपयोगी पाया, +1।
Mihai Morcov

यदि आपको एक शून्य विधि की आवश्यकता है तो यह सही उत्तर होना चाहिए।
db80

4

मेरे पास एक अलग स्थिति है, मैं voidपहली कॉल के लिए एक फ़ंक्शन का मजाक बनाना चाहता था और इसे दूसरे कॉल पर सामान्य रूप से चलाता था।

यह मेरे लिए काम करता है:

Mockito.doThrow(new RuntimeException("random runtime exception"))
       .doCallRealMethod()
       .when(spy).someMethod(Mockito.any());
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.