एक विधि हस्ताक्षर पर विचार करें जैसे:
public String myFunction(String abc);
क्या मॉकिटो उसी स्ट्रिंग को वापस करने में मदद कर सकता है जो प्राप्त विधि है?
एक विधि हस्ताक्षर पर विचार करें जैसे:
public String myFunction(String abc);
क्या मॉकिटो उसी स्ट्रिंग को वापस करने में मदद कर सकता है जो प्राप्त विधि है?
जवाबों:
आप मॉकिटो में एक उत्तर बना सकते हैं। चलिए मान लेते हैं, हमारे पास एक एप्लीकेशन है जिसका नाम है एप्लीकेशन विथ ए मेथफंक्शन।
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]);
when(...).then(Return.firstParameter())
when(foo(any()).then(i -> i.getArgumentAt(0, Bar.class))
। और आप बस एक विधि संदर्भ का उपयोग कर सकते हैं और वास्तविक विधि को कॉल कर सकते हैं।
Iterator<? extends ClassName>
जो एक thenReturn()
बयान में सभी प्रकार की कास्ट समस्याओं का कारण बनता है ।
when(foo(any()).thenAnswer(i -> i.getArguments()[0])
यदि आपके पास मॉकिटो 1.9.5 या उच्चतर है, तो एक नया स्टैटिक तरीका है जो Answer
आपके लिए ऑब्जेक्ट बना सकता है । आपको कुछ लिखने की जरूरत है
import static org.mockito.Mockito.when;
import static org.mockito.AdditionalAnswers.returnsFirstArg;
when(myMock.myFunction(anyString())).then(returnsFirstArg());
या वैकल्पिक रूप से
doAnswer(returnsFirstArg()).when(myMock).myFunction(anyString());
ध्यान दें कि returnsFirstArg()
विधि AdditionalAnswers
कक्षा में स्थिर है , जो मॉकिटो 1.9.5 के लिए नया है; इसलिए आपको सही स्थैतिक आयात की आवश्यकता होगी।
when(...).then(returnsFirstArg())
, मैंने गलती से when(...).thenReturn(returnsFirstArg())
जो दिया थाjava.lang.ClassCastException: org.mockito.internal.stubbing.answers.ReturnsArgumentAt cannot be cast to
static org.mockito.AdditionalAnswers.returnsFirstArg
। यह रिटर्न का उपयोग करने के लिए। इसके अलावा, मैं when(myMock.myFunction(any())).then(returnsFirstArg())
जावा 8 के साथ मॉकिटो के पुराने संस्करण के साथ एक-पंक्ति उत्तर बनाना संभव है:
when(myMock.myFunction(anyString()).then(i -> i.getArgumentAt(0, String.class));
बेशक यह AdditionalAnswers
डेविड वैलेस द्वारा सुझाए गए उपयोग के रूप में उतना उपयोगी नहीं है , लेकिन यदि आप "मक्खी पर" तर्क को बदलना चाहते हैं तो यह उपयोगी हो सकता है।
long
, तो क्या यह अभी भी मुक्केबाजी के साथ काम कर सकता है और Long.class
?
मुझे भी इसी तरह की समस्या थी। लक्ष्य एक ऐसी सेवा का मजाक उड़ाना था जो वस्तुओं को बनाए रखता है और उन्हें उनके नाम से वापस कर सकता है। सेवा इस तरह दिखती है:
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"));
}
यह एक बहुत पुराना सवाल है, लेकिन मुझे लगता है कि अभी भी प्रासंगिक है। इसके अलावा स्वीकृत उत्तर केवल स्ट्रिंग के लिए काम करता है। इस बीच मॉकिटो 2.1 है और कुछ आयात बदल गए हैं, इसलिए मैं अपना वर्तमान जवाब साझा करना चाहूंगा:
import static org.mockito.AdditionalAnswers.returnsFirstArg;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
@Mock
private MyClass myClass;
// this will return anything you pass, but it's pretty unrealistic
when(myClass.myFunction(any())).then(returnsFirstArg());
// it is more "life-like" to accept only the right type
when(myClass.myFunction(any(ClassOfArgument.class))).then(returnsFirstArg());
MyClass.myFunction लगेगा:
public class MyClass {
public ClassOfArgument myFunction(ClassOfArgument argument){
return argument;
}
}
मैं कुछ इसी तरह का उपयोग करता हूं (मूल रूप से यह समान दृष्टिकोण है)। कभी-कभी कुछ इनपुट के लिए मॉक ऑब्जेक्ट रिटर्न पूर्व-परिभाषित आउटपुट होना उपयोगी होता है। यह इस प्रकार है:
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<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
तर्क का मूल्य स्पष्ट रूप से तर्क के माध्यम से सुलभ है। आगे के हेरफेर / जाँच / जो कुछ भी हो, के लिए मत भूलना।
यह थोड़ा पुराना है, लेकिन मैं यहां आया था क्योंकि मेरे पास एक ही मुद्दा था। मैं JUnit का उपयोग कर रहा हूं, लेकिन इस बार मजाक के साथ कोटलिन ऐप में। मैं जावा समकक्ष के संदर्भ और तुलना के लिए यहां एक नमूना पोस्ट कर रहा हूं:
@Test
fun demo() {
// mock a sample function
val aMock: (String) -> (String) = mockk()
// make it return the same as the argument on every invocation
every {
aMock.invoke(any())
} answers {
firstArg()
}
// test it
assertEquals("senko", aMock.invoke("senko"))
assertEquals("senko1", aMock.invoke("senko1"))
assertNotEquals("not a senko", aMock.invoke("senko"))
}
आप ArgumentCaptor का उपयोग करके इसे प्राप्त कर सकते हैं
कल्पना कीजिए कि आपके पास सेम फंक्शन है।
public interface Application {
public String myFunction(String abc);
}
फिर अपनी परीक्षा कक्षा में:
//Use ArgumentCaptor to capture the value
ArgumentCaptor<String> param = ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture())).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
return param.getValue();//return the captured value.
}
});
या यदि आप लैम्ब्डा के प्रशंसक हैं तो बस करें:
//Use ArgumentCaptor to capture the value
ArgumentCaptor<String> param = ArgumentCaptor.forClass(String.class);
when(mock.myFunction(param.capture()))
.thenAnswer((invocation) -> param.getValue());
सारांश: दिए गए पैरामीटर को कैप्चर करने के लिए, तर्क-वितर्क का उपयोग करें। बाद में जवाब में getValue का उपयोग करके कैप्चर किया गया मान लौटाएं।
This doesn´t work (anymore?).
मुझे यकीन नहीं है कि आपके द्वारा मेरे उदाहरण पर काम करने का क्या मतलब है । 2. क्षमा करें, मैं उस बिंदु पर स्पष्ट नहीं हूं जिसे आप बनाने की कोशिश कर रहे हैं। उत्तर ओपी के प्रश्न के लिए विशिष्ट है।