Mockito। विधि तर्कों को सत्यापित करें


220

मैंने इस बारे में गुगली की है, लेकिन प्रासंगिक कुछ भी नहीं मिला। मुझे ऐसा कुछ मिला है:

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj )).thenReturn(null);

Testeable testableObj = new Testeable();
testableObj.setMockeable(mock);
command.runtestmethod();

अब, मैं इसे सत्यापित करना चाहता हूं mymethod(Object o), जिसे अंदर कहा जाता है runtestmethod(), ऑब्जेक्ट के साथ बुलाया गया था o, किसी अन्य को नहीं। लेकिन मैं हमेशा परीक्षण पास करता हूं, जो कुछ भी मैंने सत्यापन पर रखा, उदाहरण के लिए:

Mockito.verify(mock.mymethod(Mockito.eq(obj)));

या

Mockito.verify(mock.mymethod(Mockito.eq(null)));

या

Mockito.verify(mock.mymethod(Mockito.eq("something_else")));

मैं हमेशा टेस्ट पास करता हूं। मैं उस सत्यापन को कैसे पूरा कर सकता हूं (यदि संभव हो)?

धन्यवाद।

जवाबों:


334

का एक विकल्प ArgumentMatcherहै ArgumentCaptor

आधिकारिक उदाहरण:

ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());

@ कैपटोर एनोटेशन का उपयोग करके एक कैटर को भी परिभाषित किया जा सकता है :

@Captor ArgumentCaptor<Person> captor;
//... MockitoAnnotations.initMocks(this);
@Test public void test() {
    //...
    verify(mock).doSomething(captor.capture());
    assertEquals("John", captor.getValue().getName());
}

1
नमूने के लिए धन्यवाद! कभी इसका इस्तेमाल नहीं किया। कोड में कैद जैसी चीजें होना थोड़ा अजीब लगता है , लेकिन इससे मदद मिली।
आर्टेमिस

1
हाहा, मुझे सवाल समझ में नहीं आया, लेकिन जवाब से मुझे बहुत मदद मिली। धन्यवाद :-)
मार्कस के।

13
महत्वपूर्ण: मॉक का उपयोग करने के बाद कॉल वेरिफ़िकेशन () / कैप्चर () करें । मैं सोच रहा था कि इसे पहले "स्थापित" किया जाना है ...
डैनियल एल्डर

1
इस उत्तर के लिए धन्यवाद!
जोस फ्लावियो क्विसेप इराजाल

यह एक महान जवाब है !! आपका बहुत बहुत धन्यवाद!
उल्की इगोर

61

क्या आप ऑब्जेक्ट के असमान तरीकों का उपयोग करके तार्किक समानता करने की कोशिश कर रहे हैं? आप यह मॉकिटो में शामिल argThat माचिस का उपयोग कर सकते हैं

import static org.mockito.Matchers.argThat

इसके बाद आप अपने स्वयं के तर्क मिलानकर्ता को लागू कर सकते हैं जो प्रत्येक ऑब्जेक्ट को असमान बना देगा

private class ObjectEqualityArgumentMatcher<T> extends ArgumentMatcher<T> {
    T thisObject;

    public ObjectEqualityArgumentMatcher(T thisObject) {
        this.thisObject = thisObject;
    }

    @Override
    public boolean matches(Object argument) {
        return thisObject.equals(argument);
    }
}

अब अपने कोड का उपयोग करके आप इसे पढ़ने के लिए अद्यतन कर सकते हैं ...

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj)).thenReturn(null);

Testeable obj = new Testeable();
obj.setMockeable(mock);
command.runtestmethod();

verify(mock).mymethod(argThat(new ObjectEqualityArgumentMatcher<Object>(obj)));

यदि आप सिर्फ समानता (मेमोरी में समान वस्तु) के लिए जा रहे हैं, तो बस करें

verify(mock).mymethod(obj);

यह सत्यापित करेगा कि इसे एक बार बुलाया गया था।


1
आप ReflectionEqualsउस उद्देश्य के लिए कक्षा में निर्माण का उपयोग कर सकते हैं ।
ताकसकोट

2
आपके उत्तर के लिए +1। लेकिन मैं यह जोड़ना चाहूंगा कि verify(mock).mymethod(obj);EXACT समानता (मेमोरी में समान ऑब्जेक्ट) के लिए जांच नहीं करता है। इसके बजाय यह वस्तुओं के बराबर-विधि का उपयोग करता है जिसे अधिलेखित किया जा सकता था।
efux

आप ArgumentMatcherकम क्रिया होने के लिए एक अनाम कार्यान्वयन भी बना सकते हैं ।
13

1
अधिक विवरण: डिफ़ॉल्ट रूप से / दर्ज की गई वस्तु / विधि के बजाय verify()/ इनबाउंड तर्क / equals()विधि को आमंत्रित करता है equals()। यह तब तक अप्रासंगिक है जब तक आप यह पुष्टि करने की कोशिश नहीं कर रहे हैं कि आपका परीक्षण विषय एक विशिष्ट वस्तु उदाहरण लौटाता है, और वह विषय वापस लौटता है जो उस उदाहरण के पारदर्शी सज्जाकार के रूप में माना जाता है। verifyतर्क के equals()डेकोरेटर के बारे में पता नहीं होता; जबकि डेकोरेटर equals()को मूल को बर्दाश्त करने के लिए फिर से लिखा जाएगा। इस उदाहरण में आपका परीक्षण गलत तरीके से विफल हो जाएगा।
मार्क मैककेना

54
  • eqयदि आपको अन्य मिलानकर्ताओं का उपयोग नहीं करना है, तो आपको मिलानकर्ता की आवश्यकता नहीं है।
  • आप सही सिंटैक्स का उपयोग नहीं कर रहे हैं - आपकी विधि कॉल बाहर होनी चाहिए .verify(mock)। अब आप विधि कॉल के परिणाम पर सत्यापन शुरू कर रहे हैं, बिना किसी सत्यापन के (विधि कॉल नहीं करने पर)। इसलिए सभी टेस्ट पास कर रहे हैं।

आपको कोड दिखना चाहिए:

Mockito.verify(mock).mymethod(obj);
Mockito.verify(mock).mymethod(null);
Mockito.verify(mock).mymethod("something_else");

मैंने कोशिश की कि पहले, और अब फिर से सुनिश्चित हो। मुझे अभी भी वही समस्या है, परीक्षा हमेशा पास होती है।
मनोलोवर

2
यह संदर्भ द्वारा सत्यापित करता है
cnexans

17

argThat साथ ही लंबोदर

यह है कि आप अपने तर्क सत्यापन को कैसे विफल कर सकते हैं:

    verify(mock).mymethod(argThat(
      (x)->false
    ));

कहाँ पे

import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.verify;

argThat साथ ही जोर देता है

उपरोक्त परीक्षण "कहेंगे" Expected: lambda$... Was: YourClass.toSting...। यदि आप लंबोदर में मुखर का उपयोग करते हैं, तो आप विफलता का अधिक विशिष्ट कारण प्राप्त कर सकते हैं:

    verify(mock).mymethod(argThat( x -> {
      assertThat(x).isNotNull();
      assertThat(x.description).contains("KEY");
      return true;
    }));

लेकिन: केवल 1 मेटल कॉल के साथ काम करता है। यदि सत्यापित विधि जिसे 2+ बार कहा जाता है, तो मॉकिटो सभी कहे जाने वाले संयोजनों को प्रत्येक सत्यापनकर्ता को पास करता है। तो मॉकिटो को उम्मीद है कि आपके सत्यापनकर्ता ने चुपचाप trueएक तर्क सेट के लिए रिटर्न किया, और falseअन्य वैध कॉल के लिए (कोई अपवाद नहीं)। वह अपेक्षा 1 विधि कॉल के लिए कोई समस्या नहीं है - इसे केवल 1 बार सही लौटना चाहिए।

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.verify;

अब परीक्षण कहता है Expected: Obj.description to contain 'KEY'. Was: 'Actual description':। ध्यान दें: मैंने assertJदावा किया था , लेकिन यह आपके ऊपर निर्भर है कि किस रूपरेखा का उपयोग करना है।


argThat कई तर्कों के साथ।

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

    verify(mock).mymethod(eq("VALUE_1"), argThat((x)->false));
    // above is correct as eq() is also an argument matcher.

verify(mock).mymethod("VALUE_1", argThat((x)->false));

// above is incorrect; an exceptoin will be thrown, as the fist arg. is given without an argument matcher.

कहाँ पे:

import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;

eq मिलान

यह जांचने का सबसे आसान तरीका है कि क्या तर्क समान है:

verify(mock).mymethod(eq(expectedValue));
// NOTE:   ^ where the parentheses must be closed.

प्रत्यक्ष तर्क

यदि रेफरी द्वारा तुलना स्वीकार्य है, तो इसके साथ चलें:

verify(mock).mymethod(expectedArg);
// NOTE:   ^ where the parentheses must be closed.

मूल प्रश्न विफलता का जड़ पक्षगणों का गलत स्थान था verify(mock.mymethod...:। वह गलत था। सही होगा:verify(mock).*


1
यह मेरा पसंदीदा उत्तर है, काम करता है और दूसरों की तुलना में अधिक सुरुचिपूर्ण है।
Airwavezx

11

मैंने इस तरह से मॉकिटो का उपयोग किया है

@UnitTest
public class JUnitServiceTest
{
    @Mock
    private MyCustomService myCustomService;


    @Test
    public void testVerifyMethod()
    {
       Mockito.verify(myCustomService, Mockito.never()).mymethod(parameters); // method will never call (an alternative can be pick to use times(0))
       Mockito.verify(myCustomService, Mockito.times(2)).mymethod(parameters); // method will call for 2 times
       Mockito.verify(myCustomService, Mockito.atLeastOnce()).mymethod(parameters); // method will call atleast 1 time
       Mockito.verify(myCustomService, Mockito.atLeast(2)).mymethod(parameters); // method will call atleast 2 times
       Mockito.verify(myCustomService, Mockito.atMost(3)).mymethod(parameters); // method will call at most 3 times
       Mockito.verify(myCustomService, Mockito.only()).mymethod(parameters); //   no other method called except this
    }
}

5

क्या आपने नकली वर्ग के लिए समान पद्धति की जाँच की है? यदि यह रिटर्न हमेशा सही रहता है या आप एक ही उदाहरण के खिलाफ एक ही उदाहरण का परीक्षण करते हैं और समान पद्धति को अधिलेखित नहीं किया जाता है (और केवल संदर्भों के खिलाफ जांच होती है), तो यह सच है।


4

अन्य विधि का उपयोग करना है। org.mockito.internal.matchers.Equals.Equals के बदले विधि को फिर से परिभाषित करना है:

verify(myMock).myMethod((inputObject)Mockito.argThat(new Equals(inputObjectWanted)));

3

क्या आपने इसे उसी () मिलानकर्ता के साथ आजमाया है? जैसे की:

verify(mockObj).someMethod(same(specificInstance));

मुझे भी यही समस्या थी। मैंने इसे eq () मिलानकर्ता के साथ-साथ RefEq () मिलानकर्ता के साथ आजमाया लेकिन मेरे पास हमेशा गलत सकारात्मकता थी। जब मैंने एक ही () माचिस का उपयोग किया, तो तर्कों के अलग-अलग उदाहरण होने के बाद परीक्षण विफल हो गया और एक बार तर्क पारित होने के बाद एक ही उदाहरण था।


-1

आप TypeSafeDiagnosingMatcher का भी उपयोग कर सकते हैं

    private Matcher<GetPackagesRequest> expectedPackageRequest(final AvailabilityRequest request) {
    return new TypeSafeDiagnosingMatcher<GetPackagesRequest>() {

        StringBuilder text = new StringBuilder(500);

        @Override
        protected boolean matchesSafely(GetPackagesRequest req, Description desc) {
            String productCode = req.getPackageIds().iterator().next().getValue();
            if (productCode.equals(request.getSupplierProductCode())) {
                text.append("ProductCode not equal! " + productCode + " , " + request.getSupplierProductCode());
                return true;
            }

            text.append(req.toString());
            return false;
        }

        @Override
        public void describeTo(Description d) {
            d.appendText(text.toString());
        }
    };
}

फिर उस आह्वान को सत्यापित करें:

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