java - मैं एक विधि कैसे वापस कर सकता हूँ एक तर्क है कि इसे पारित किया गया था?


इस तरह एक विधि हस्ताक्षर पर विचार करें:

public String myFunction(String abc);

Mockito मदद कर सकता है एक ही स्ट्रिंग कि विधि प्राप्त वापसी?



Answers



आप मोकीटो में एक उत्तर बना सकते हैं। मान लीजिए, हमारे पास मेरे फ़ंक्शन के एक विधि के साथ एक इंटरफ़ेस नाम का इंटरफ़ेस है।

public interface Application {
  public String myFunction(String abc);
}

यहां एक मोकीकी उत्तर के साथ परीक्षण विधि है:

public void testMyFunction() throws Exception {
  Application mock = mock(Application.class);
  when(mock.myFunction(anyString())).thenAnswer(new Answer<String>() {
    @Override
    public String answer(InvocationOnMock invocation) throws Throwable {
      Object[] args = invocation.getArguments();
      return (String) args[0];
    }
  });

  assertEquals("someString",mock.myFunction("someString"));
  assertEquals("anotherString",mock.myFunction("anotherString"));
}

चूंकि मैककीटो 1.9.5 और जावा 8 लैम्ब्डा फ़ंक्शंस का उपयोग करके एक आसान तरीका है:

when(myMock.myFunction(anyString())).thenAnswer(i -> i.getArguments()[0]);




अगर आपके पास मॉकिटो 1.9.5 या उच्चतर है, तो एक नई स्थिर विधि है जो आपके लिए Answer वस्तु बना सकती है। आपको कुछ लिखने की जरूरत है

when(myMock.myFunction(anyString())).then(returnsFirstArg());

या वैकल्पिक रूप से

doAnswer(returnsFirstArg()).when(myMock).myFunction(anyString());

ध्यान दें कि returnsFirstArg() विधि AdditionalAnswers returnsFirstArg() क्लास में स्थिर है, जो कि returnsFirstArg() 1.9.5; तो आपको सही स्थैतिक आयात की आवश्यकता होगी




जावा 8 के साथ Mockito के पुराने संस्करण के साथ भी एक एक-लाइन का उत्तर बनाना संभव है:

when(myMock.myFunction(anyString()).then(i -> i.getArgumentAt(0, String.class));

बेशक यह डेविड वलस द्वारा सुझाए गए AdditionalAnswers नर्सों के उपयोग के रूप में उपयोगी नहीं है, लेकिन यदि आप "मक्खी पर" तर्क बदलना चाहते हैं तो उपयोगी हो सकता है।




मेरे पास बहुत ही समान समस्या थी उद्देश्य एक सेवा का मजाक बनाना था जो ऑब्जेक्ट जारी रखता है और उनके नाम से उन्हें वापस कर सकता है। सेवा इस तरह दिखती है:

public class RoomService {
    public Room findByName(String roomName) {...}
    public void persist(Room room) {...}
}

सेवा नकली कमरे के उदाहरणों को स्टोर करने के लिए मानचित्र का उपयोग करता है

RoomService roomService = mock(RoomService.class);
final Map<String, Room> roomMap = new HashMap<String, Room>();

// mock for method persist
doAnswer(new Answer<Void>() {
    @Override
    public Void answer(InvocationOnMock invocation) throws Throwable {
        Object[] arguments = invocation.getArguments();
        if (arguments != null && arguments.length > 0 && arguments[0] != null) {
            Room room = (Room) arguments[0];
            roomMap.put(room.getName(), room);
        }
        return null;
    }
}).when(roomService).persist(any(Room.class));

// mock for method findByName
when(roomService.findByName(anyString())).thenAnswer(new Answer<Room>() {
    @Override
    public Room answer(InvocationOnMock invocation) throws Throwable {
        Object[] arguments = invocation.getArguments();
        if (arguments != null && arguments.length > 0 && arguments[0] != null) {
            String key = (String) arguments[0];
            if (roomMap.containsKey(key)) {
                return roomMap.get(key);
            }
        }
        return null;
    }
});

अब हम इस मॉक पर हमारे परीक्षण चला सकते हैं। उदाहरण के लिए:

String name = "room";
Room room = new Room(name);
roomService.persist(room);
assertThat(roomService.findByName(name), equalTo(room));
assertNull(roomService.findByName("none"));



जावा 8 के साथ, स्टीव का उत्तर बन सकता है

public void testMyFunction() throws Exception {
    Application mock = mock(Application.class);
    when(mock.myFunction(anyString())).thenAnswer(
    invocation -> {
        Object[] args = invocation.getArguments();
        return args[0];
    });

    assertEquals("someString", mock.myFunction("someString"));
    assertEquals("anotherString", mock.myFunction("anotherString"));
}

संपादित करें: छोटा भी:

public void testMyFunction() throws Exception {
    Application mock = mock(Application.class);
    when(mock.myFunction(anyString())).thenAnswer(
        invocation -> invocation.getArgument(0));

    assertEquals("someString", mock.myFunction("someString"));
    assertEquals("anotherString", mock.myFunction("anotherString"));
}



मैं कुछ इसी तरह का उपयोग करता हूँ (मूल रूप से यह वही दृष्टिकोण है) कभी-कभी यह उपयोगी होता है कि कुछ आदानों के लिए नकली वस्तु पूर्व-परिभाषित आउटपुट वापस लाती है। यह इस तरह से चला जाता है:

private Hashtable<InputObject,  OutputObject> table = new Hashtable<InputObject, OutputObject>();
table.put(input1, ouput1);
table.put(input2, ouput2);

...

when(mockObject.method(any(InputObject.class))).thenAnswer(
       new Answer<OutputObject>()
       {
           @Override
           public OutputObject answer(final InvocationOnMock invocation) throws Throwable
           {
               InputObject input = (InputObject) invocation.getArguments()[0];
               if (table.containsKey(input))
               {
                   return table.get(input);
               }
               else
               {
                   return null; // alternatively, you could throw an exception
               }
           }
       }
       );



आप ArgumentCaptor के साथ संयोजन में मूल्यांकन () का प्रयोग करना चाहते हैं ताकि परीक्षण में निष्पादन सुनिश्चित किया जा सके और तर्कों का मूल्यांकन करने के लिए ArgumentCaptor हो सकता है:

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());

तर्क का मूल्य स्पष्ट रूप से तर्क के माध्यम से पहुंचा जा सकता है। GetValue () और आगे हेरफेर / जांच / जो भी हो








Links