조롱당한 방법을 만들면 그에 전달된 인수를 반환한다.
다음과 같은 메서드 시그니처를 검토합니다.
public String myFunction(String abc);
Mockito는 메서드가 받은 것과 동일한 문자열을 반환할 수 있습니까?
Mockito에서 Answer를 생성할 수 있습니다.예를 들어 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()method는 에서는 스태틱한AdditionalAnswersMockito 1.9.5에서는 새로운 클래스이므로 적절한 스태틱 Import가 필요합니다.
Java 8에서는 이전 버전의 Mockito에서도 한 줄의 답변을 작성할 수 있습니다.
when(myMock.myFunction(anyString()).then(i -> i.getArgumentAt(0, String.class));
물론 이 기능은 사용법만큼 유용하지는 않습니다.AdditionalAnswersDavid Wallace가 제안했지만 "on the fly" 인수를 변환하려는 경우 유용할 수 있습니다.
저도 비슷한 문제가 있었어요.목표는 개체를 유지하고 개체를 이름으로 반환할 수 있는 서비스를 조롱하는 것이었습니다.서비스는 다음과 같습니다.
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"));
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"));
}
이것은 꽤 오래된 질문이지만 나는 여전히 관련이 있다고 생각한다.또한 허용되는 답변은 String에만 적용됩니다.한편, Mockito 2.1이 있어, Import가 변경되고 있기 때문에, 현재의 회답은 다음과 같습니다.
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.my함수는 다음과 같습니다.
public class MyClass {
public ClassOfArgument myFunction(ClassOfArgument argument){
return argument;
}
}
이건 좀 오래된 건데, 같은 문제가 있어서 왔어요.JUnit을 쓰고 있는데 이번에는 Mockk가 있는 Kotlin 앱에서.Java와의 비교 및 참조를 위해 샘플을 여기에 게시합니다.
@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"))
}
Argument Captor를 사용하면 이 작업을 수행할 수 있습니다.
이렇게 콩 기능이 있다고 상상해 보세요.
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());
개요:전달된 매개 변수를 캡처하려면 argumentcapter를 사용합니다.나중에 getValue를 사용하여 캡처한 값을 반환합니다.
verify()를 ArgumentCaptor 및 ArgumentCaptor와 조합하여 테스트 실행을 확인하고 ArgumentCaptor를 사용하여 인수를 평가할 수 있습니다.
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());
인수 값은 인수.getValue()를 통해 추가 조작/체크/무엇을 위해 액세스할 수 있습니다.
저는 비슷한 것을 사용합니다(기본적으로 같은 접근법입니다).특정 입력에 대해 미리 정의된 출력을 반환하는 모의 객체가 유용할 수 있습니다.그 내용은 다음과 같습니다.
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
}
}
}
);
언급URL : https://stackoverflow.com/questions/2684630/making-a-mocked-method-return-an-argument-that-was-passed-to-it
'programing' 카테고리의 다른 글
| C의 i++와 (i)++의 차이 (0) | 2022.08.29 |
|---|---|
| 페이지를 새로 고친 후 Vuex가 검색되지 않는 이유는 무엇입니까?(nuxt) (0) | 2022.08.29 |
| vue 루프에서 요소의 색상을 동적으로 변경 (0) | 2022.08.29 |
| String.equals 대 == (0) | 2022.08.29 |
| Vue 인스턴스 시작 시 Vuex 자체 내에서 액션을 디스패치할 수 있습니까? (0) | 2022.08.29 |