다음과 같은 메소드 서명을 고려하십시오.
public String myFunction(String abc);
Mockito가 메소드가 수신 한 것과 동일한 문자열을 리턴하도록 도울 수 있습니까?
답변
Mockito에서 답변을 만들 수 있습니다. myFunction 메소드가있는 Application이라는 인터페이스가 있다고 가정 해 봅시다.
public interface Application {
public String myFunction(String abc);
}
Mockito 답변이있는 테스트 방법은 다음과 같습니다.
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"));
}
Mockito 1.9.5 및 Java 8부터 람다 식을 사용할 수도 있습니다.
when(myMock.myFunction(anyString())).thenAnswer(i -> i.getArguments()[0]);
답변
Mockito 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
클래스 에서 정적이며 Mockito 1.9.5에 새로 도입되었습니다. 올바른 정적 가져 오기가 필요합니다.
답변
Java 8을 사용하면 이전 버전의 Mockito에서도 한 줄 답변을 만들 수 있습니다.
when(myMock.myFunction(anyString()).then(i -> i.getArgumentAt(0, String.class));
물론 이것은 AdditionalAnswers
David Wallace가 제안한 것만 큼 유용 하지는 않지만 “즉시”인수를 변환하려는 경우 유용 할 수 있습니다.
답변
나는 비슷한 문제가 있었다. 목표는 객체를 유지하고 이름으로 반환 할 수있는 서비스를 조롱하는 것이 었습니다. 서비스는 다음과 같습니다.
public class RoomService {
public Room findByName(String roomName) {...}
public void persist(Room 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"));
답변
Java 8을 사용하면 Steve의 대답 이 될 수 있습니다.
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"));
}
답변
이것은 꽤 오래된 질문이지만 여전히 관련이 있다고 생각합니다. 또한 허용되는 답변은 문자열에만 적용됩니다. 한편 Mockito 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
}
}
}
);
