विभिन्न पैरामेट्स के साथ कई विधि कॉलों को कैसे सत्यापित करें


116

मेरे पास निम्नलिखित विधि है जिसे मैं व्यवहार को सत्यापित करना चाहता हूं।

public void methodToTest(Exception e, ActionErrors errors) {
    ...

    errors.add("exception.message", 
            ActionMessageFactory.createErrorMessage(e.toString()));

    errors.add("exception.detail",
            ActionMessageFactory.createErrorMessage(e.getStackTrace()[0].toString()));

    ...
}

मेरी @Test कक्षा में मैं यह सत्यापित करने के लिए कुछ ऐसा करने की उम्मीद कर रहा था errors.add()जिसे "अपवाद सुबह " कहा जाता है और फिर से " अपवाद.डेट "

verify(errors).add(eq("exception.message"), any(ActionError.class));
verify(errors).add(eq("exception.detail"), any(ActionError.class));

हालांकि मॉकिटो निम्नानुसार शिकायत करता है

Argument(s) are different! Wanted:
actionErrors.add(
    "exception.message",
    <any>
);

Actual invocation has different arguments:
actionErrors.add(
    "exception.detail",
    org.apache.struts.action.ActionError@38063806
);

मैं मॉकिटो को दोनों मूल्यों की जांच करने के लिए कैसे कह सकता हूं?


1
जब आपके पास अलग-अलग हस्ताक्षर के साथ 2 विधियां हैं, तो आप दोनों के लिए अलग-अलग परीक्षण मामला लिख ​​सकते हैं।
नवीन बाबू

8
हां, लेकिन इस मामले में इसका एक ही तरीका है हस्ताक्षर लेकिन सिर्फ अलग तर्क मान
ब्रैड

आप उपयोग करने की कोशिश कर सकते हैंMockito.reset()
takacsot

जवाबों:


102

आगे पढ़ने से मुझे ArgumentCaptors और निम्नलिखित कार्यों का उपयोग करने की कोशिश करने के लिए प्रेरित किया गया है, हालांकि मैं जितना चाहूंगा उससे कहीं अधिक क्रिया।

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);

verify(errors, atLeastOnce()).add(argument.capture(), any(ActionMessage.class));

List<String> values = argument.getAllValues();

assertTrue(values.contains("exception.message"));
assertTrue(values.contains("exception.detail"));

क्या यह सुनिश्चित करने का एक तरीका है कि कुछ मापदंडों को इस दृष्टिकोण का उपयोग करके जोड़ा गया था? कहते हैं, उदाहरण के लिए ओपी की विधि दो तर्क था और सत्यापित करने के लिए करना चाहता था वे एक साथ कहा जाता था
committedandroider

1
ओपी का परीक्षण मामला methodToTest()ठीक एक बार कॉल करता है, इसलिए यह जवाब सत्यापित करता है कि दो कॉल एक साथ किए गए हैं। कब्जा कर लिया गया है List<String> valuesकि केवल दो मूल्यों का परीक्षण किया जाएगा और कोई अन्य नहीं होगा। आप भी जोड़ सकते हैं assertTrue(values.size == 2)। अगर यह है कि आप चाहते हैं कि मैं 3 मुखर बयानों को एक ही हैमरेस्ट के साथ बदल दूंगा ...assertThat(values, contains("exception.message", "exception.detail"));
ब्रैड

क्या OP का परीक्षण केस कॉल विधिToTest () दो बार नहीं है?
committedandroider

क्षमा करें, मैं स्पष्ट नहीं था। मैं उस परिदृश्य का जिक्र कर रहा था, जहां ओपी यह परीक्षण करना चाहता था कि दो तर्कों को संयोजन के रूप में बुलाया गया था। इसलिए विधि हस्ताक्षर सार्वजनिक शून्य विधि की तरह कुछ दिखाई देगा ।Test (Exception e, Message m, ActionErrors त्रुटियाँ) {ताकि एक विशिष्ट अपवाद को एक विशिष्ट संदेश के साथ बुलाया जाता है। मेरा मानना ​​था कि आपके पास सिर्फ दो ArgumentCaptors हो सकते हैं और फिर इंडेक्स को पुनः प्राप्त कर सकते हैं और उन इंडेक्स में मानों का उपयोग करके दोनों मान सूचियों में तुलना कर सकते हैं
प्रतिबद्ध

ओपी का परीक्षण मामला methodToTest()एक बार कॉल करता है । यह विधि का तर्क ActionErrors errorsहै जिसे आंतरिक रूप से दो बार कहा जाता है।
ब्रैड

61

यदि दोनों add()कॉल का क्रम प्रासंगिक है, तो आप उपयोग कर सकते हैं InOrder:

InOrder inOrder = inOrder(errors);
inOrder.verify(errors).add(eq("exception.message"), any(ActionError.class));
inOrder.verify(errors).add(eq("exception.detail"), any(ActionError.class));

7
यह एकल errorsतर्क को पारित करने के लिए पर्याप्त है : InOrder inOrder = inOrder(errors);( डॉक्स देखें )
ग्रीनहाउसवेग

2
क्या होगा यदि आदेश प्रासंगिक नहीं है? जो अक्सर होता है।
हेलिक्स

1
@haelix उस मामले में, ब्रैड्स उत्तर का उपयोग करें। कन्वर्ट Listकरने के लिए Setऔर ज़ोर कि आदानों की सेट तर्क कैप्चर द्वारा दिए गए सेट बराबर होती है।
फ़्लॉपशॉट

25

कुछ इस तरह की कोशिश करो:

verify(errors, times(2))
     .add(AdditionalMatchers.or(eq("exception.message"), eq("exception.detail")),
          any(ActionError.class));

4
आपका चेक स्पष्ट रूप से बहुत आराम से है।
हेलिक्स

17

आपको शायद अपने कोड में कोई समस्या है। क्योंकि वास्तव में आप वास्तव में इस कोड को लिखते हैं:

Map<Character, String> map = mock(Map.class);

map.put('a', "a");
map.put('b', "b");
map.put('c', "c");

verify(map).put(eq('c'), anyString());
verify(map).put(eq('a'), anyString());
verify(map).put(eq('b'), anyString());

ध्यान दें कि वास्तविक चालान के संबंध में पहला सत्यापन भी नहीं है।

इसके अलावा, मैं आपको सलाह दूंगा कि आप वास्तव में उन प्रकारों का मजाक न करें, जो आपके पास नहीं हैं, जैसे कि स्ट्रट्स टाइप।

[EDIT @Brad]

अपने IDE में Brice का कोड (ऊपर) चलाने के बाद, मैं देख सकता हूं कि मैंने ActionMessage के बजाय ActionError का उपयोग किया है, इसीलिए मेरा सत्यापन () मेल नहीं खा रहा था। त्रुटि संदेश जो मैंने शुरू में पोस्ट किया था वह मुझे यह सोचकर गुमराह कर रहा था कि यह पहला तर्क था जो मेल नहीं खा रहा था। यह पता चला है कि यह दूसरा तर्क था।

तो मेरे सवाल का जवाब है

/** 
 * note that ActionMessageFactory.createErrorMessage() returns ActionMessage
 * and ActionError extends ActionMessage
 */
verify(errors).add(eq("exception.message"), any(ActionMessage.class));
verify(errors).add(eq("exception.detail"), any(ActionMessage.class));

1
डॉन `टी तुम क्या कहने की कोशिश कर रहे हैं। सत्यापन मामलों का आदेश है? यदि सत्यापन आदेश मायने रखता है। फिर यहाँ InOrder एपीआई क्यों प्रदान किया गया है?
ऑलेक्ज़ेंडर पापचेंको 13

सत्यापन आदेश के ऊपर जो कुछ लिखा गया है, वह अप्रासंगिक है; इसीलिए वहाँ है InOrder
ब्रिस

12

आप उपयोग कर सकते हैं Mockito.atLeastOnce()जो मॉकिटो को परीक्षण पास करने की अनुमति देता है, भले ही उस मॉकबॉजेक्ट को कई बार कहा जाएगा।

Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(1));

Mockito.verify(mockObject, Mockito.atLeastOnce()).testMethod(Mockito.eq(2));

1

1) मोकितो को कुल कॉल की उम्मीद बताएं।

2) मोकितो को बताएं कि प्रत्येक पैरामीटर संयोजन कितनी बार अपेक्षित था।

verify(errors, times(2)).add(any(), any(ActionMessage.class));

verify(errors, atLeastOnce()).add(eq("exception.message"), any());
verify(errors, atLeastOnce()).add(eq("exception.detail"), any());

0

@ Sendon1928 के समान तरीके से हम उपयोग कर सकते हैं:

Mockito.times(wantedInvocationCount)

यह सुनिश्चित करने के लिए कि विधि को सटीक संख्या कहा जाता है (मेरी राय में बेहतर समाधान)। बाद में, हम कॉल कर सकते हैं

Mockito.verifyNoMoreInteractions(mock)

यह सुनिश्चित करने के लिए कि किसी भी संदर्भ में नकली का आगे उपयोग नहीं किया गया था। पूर्ण उदाहरण:

Mockito.verify(mockObject, Mockito.times(wantedInvocationCount)).testMethod(Mockito.eq(1));

Mockito.verify(mockObject, Mockito.times(wantedInvocationCount)).testMethod(Mockito.eq(2));

Mockito.verifyNoMoreInteractions(mockObject)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.