একটি পদ্ধতি স্বাক্ষর বিবেচনা করুন:
public String myFunction(String abc);
মকিটো পদ্ধতিটি যে স্ট্রিংটি পেয়েছে একই স্ট্রিংটি ফিরে আসতে সহায়তা করতে পারে?
একটি পদ্ধতি স্বাক্ষর বিবেচনা করুন:
public String myFunction(String abc);
মকিটো পদ্ধতিটি যে স্ট্রিংটি পেয়েছে একই স্ট্রিংটি ফিরে আসতে সহায়তা করতে পারে?
উত্তর:
আপনি মকিতোতে একটি উত্তর তৈরি করতে পারেন। ধরা যাক, আমাদের একটি অ্যাপ্লিকেশন নামক একটি ইন্টারফেস রয়েছে যার সাথে একটি পদ্ধতি myFunction রয়েছে।
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"));
}
মকিতো ১.৯.৫ এবং জাভা ৮, যেহেতু আপনি ল্যাম্বডা এক্সপ্রেশনও ব্যবহার করতে পারেন:
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ক্লাসে স্থির , যা মকিতো ১.৯.৫ এ নতুন; সুতরাং আপনার সঠিক স্ট্যাটিক আমদানি লাগবে।
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"));
}
এটি বেশ পুরানো প্রশ্ন তবে আমি এখনও প্রাসঙ্গিক বলে মনে করি। এছাড়াও গৃহীত উত্তরটি কেবল স্ট্রিংয়ের পক্ষে কাজ করে। ইতিমধ্যে মকিতো ২.১ রয়েছে এবং কিছু আমদানি পরিবর্তিত হয়েছে, তাই আমি আমার বর্তমান উত্তরটি ভাগ করতে চাই:
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<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
আরও হেরফের / চেকিং / যাই হোক না কেন, যুক্তির মানটি আর্গুমেন্টের মাধ্যমে স্পষ্টতই অ্যাক্সেসযোগ্য checking
এটি কিছুটা পুরানো, তবে আমি এখানে এসেছি কারণ আমার একই সমস্যা ছিল। আমি 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"))
}
আপনি আরগমেন্ট ক্যাপ্টর ব্যবহার করে এটি অর্জন করতে পারেন
আপনি যেমন শিম ফাংশন আছে কল্পনা।
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?).আমার উদাহরণে এটি কাজ করছে। ২. দুঃখিত, আপনি যে পয়েন্টটি তৈরি করার চেষ্টা করছেন তাতে আমি পরিষ্কার নই। উত্তরটি ওপির প্রশ্নের সাথে সুনির্দিষ্ট।