모의 메서드가 전달 된 인수를 반환하도록 만들기
다음과 같은 메소드 서명을 고려하십시오.
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"));
}
나는 비슷한 것을 사용합니다 (기본적으로 동일한 접근 방식입니다). 때때로 모의 객체가 특정 입력에 대해 미리 정의 된 출력을 반환하도록하는 것이 유용합니다. 다음과 같이 진행됩니다.
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
}
}
}
);
This is a pretty old question but i think still relevant. Also the accepted answer works only for String. Meanwhile there is Mockito 2.1 and some imports have changed, so i would like to share my current answer:
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());
The myClass.myFunction would look like:
public class MyClass {
public ClassOfArgument myFunction(ClassOfArgument argument){
return argument;
}
}
You might want to use verify() in combination with the ArgumentCaptor to assure execution in the test and the ArgumentCaptor to evaluate the arguments:
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
The argument's value is obviously accessible via the argument.getValue() for further manipulation / checking /whatever.
'Nice programing' 카테고리의 다른 글
속성 값을 기준으로 JavaScript 개체 정렬 (0) | 2020.10.02 |
---|---|
자바 스크립트로 오디오를 재생 하시겠습니까? (0) | 2020.10.02 |
벡터에 벡터 추가 (0) | 2020.10.02 |
사용자가 입력을 멈출 때까지 .keyup () 핸들러를 지연시키는 방법은 무엇입니까? (0) | 2020.10.02 |
Vi에서 전체 파일의 들여 쓰기를 어떻게 수정합니까? (0) | 2020.10.02 |