Mockito에서 varargs를 적절하게 일치시키는 방법
Mockito를 사용하여 varg 파라미터를 사용하여 메서드를 시뮬레이션하려고 합니다.
interface A {
B b(int x, int y, C... c);
}
A a = mock(A.class);
B b = mock(B.class);
when(a.b(anyInt(), anyInt(), any(C[].class))).thenReturn(b);
assertEquals(b, a.b(1, 2));
이것은 동작하지 않습니다만, 이것을 대신하면 다음과 같습니다.
when(a.b(anyInt(), anyInt())).thenReturn(b);
assertEquals(b, a.b(1, 2));
메서드를 스텁할 때 varargs 인수를 완전히 생략했는데도 이 방법은 작동합니다.
단서는?
Mockito 1.8.1에서는 anyVarg() 매처가 도입되었습니다.
when(a.b(anyInt(), anyInt(), Matchers.<String>anyVararg())).thenReturn(b);
이력에 대해서는, https://code.google.com/archive/p/mockito/issues/62 를 참조해 주세요.
폐지 후 새 구문 편집:
when(a.b(anyInt(), anyInt(), ArgumentMatchers.<String>any())).thenReturn(b);
문서화되어 있지 않은 기능:varararg 인수와 일치하는 커스텀매처를 개발하려면 구현해야 합니다.org.mockito.internal.matchers.VarargMatcher
올바르게 동작하도록 합니다.이것은 빈 마커 인터페이스입니다.Mockito가 없으면 Matcher를 사용하여 메서드를 vargs로 호출할 때 인수를 올바르게 비교할 수 없습니다.
예를 들어 다음과 같습니다.
class MyVarargMatcher extends ArgumentMatcher<C[]> implements VarargMatcher {
@Override public boolean matches(Object varargArgument) {
return /* does it match? */ true;
}
}
when(a.b(anyInt(), anyInt(), argThat(new MyVarargMatcher()))).thenReturn(b);
Eli Levine의 답변을 바탕으로 한 보다 일반적인 솔루션이 있습니다.
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.mockito.ArgumentMatcher;
import org.mockito.internal.matchers.VarargMatcher;
import static org.mockito.Matchers.argThat;
public class VarArgMatcher<T> extends ArgumentMatcher<T[]> implements VarargMatcher {
public static <T> T[] varArgThat(Matcher<T[]> hamcrestMatcher) {
argThat(new VarArgMatcher(hamcrestMatcher));
return null;
}
private final Matcher<T[]> hamcrestMatcher;
private VarArgMatcher(Matcher<T[]> hamcrestMatcher) {
this.hamcrestMatcher = hamcrestMatcher;
}
@Override
public boolean matches(Object o) {
return hamcrestMatcher.matches(o);
}
@Override
public void describeTo(Description description) {
description.appendText("has varargs: ").appendDescriptionOf(hamcrestMatcher);
}
}
그런 다음 다음과 같이 햄크레스트 배열 매처와 함께 사용할 수 있습니다.
verify(a).b(VarArgMatcher.varArgThat(
org.hamcrest.collection.IsArrayContaining.hasItemInArray("Test")));
(분명히 정적 Import를 하면 읽기 쉬워집니다.)
저는 Peter Westmacott의 답변에 있는 코드를 사용해 왔습니다만, Mockito 2.2.15를 사용하면 다음을 수행할 수 있습니다.
verify(a).method(100L, arg1, arg2, arg3)
어디에arg1, arg2, arg3
varargs입니다.
톱셰프의 답변을 바탕으로
2.0.31 베타에서는 Mockito를 사용해야 했습니다.matchers 대신 anyVararg:
when(a.b(anyInt(), anyInt(), Mockito.<String>anyVararg())).thenReturn(b);
이 경우 인수를 캡처하는 메서드의 시그니처는 다음과 같습니다.
public byte[] write(byte ... data) throws IOException;
이 경우 바이트 배열에 명시적으로 캐스트해야 합니다.
when(spi.write((byte[])anyVararg())).thenReturn(someValue);
모키토 버전을 사용하고 있습니다.1.10.19
인수를 루프 오버할 수도 있습니다.
Object[] args = invocation.getArguments();
for( int argNo = 0; argNo < args.length; ++argNo) {
// ... do something with args[argNo]
}
예를 들어, 유형을 확인하고 적절히 캐스팅하거나 목록에 추가하거나 합니다.
@topchef의 답변을 수정하여
Mockito.when(a.b(Mockito.anyInt(), Mockito.anyInt(), Mockito.any())).thenReturn(b);
Mockito 2.23.4의 Java 문서에 따르면 Mockito.any()는 "null과 varargs를 포함한 모든 것과 일치합니다."
이를 수행하려면 ArgumentCaptor 캡처를 전달하고 "getAllValues"를 사용하여 목록으로 varargs를 가져옵니다.https://stackoverflow.com/a/55621731/11342928 를 참조하십시오.
다른 답변은 타당하고 테스트도 확실히 이루어지므로, 저는 여전히 메서드가 가변값이 아닌 일반적인 파라미터로 테스트하는 것을 권장합니다.이는 SLF4J-logger와 같이 모호한 파라미터와 관련하여 오버라이드된 메서드가 있는 경우에 도움이 됩니다.
테스트 대상:
jobLogger.info("{} finished: {} tasks processed with {} failures, took {}", jobName, count, errors, duration);
여기에는 많은 오버라이드가 있으며 중요한 방법은 다음과 같이 선언됩니다.
Logger.info(String, Object...)
확인:
verify(loggerMock).info(anyString(), anyString(), anyInt(), anyInt(), anyString());
의 기능이 「상기」로서 하고 있는 합니다.errors
이며 길지 다음 항목은
verify(loggerMock).info(anyString(), anyString(), anyInt(), anyLong(), anyString());
쓸 수 요.when()
verify()
- - . - stuff. - stuff.
그리고 아마도 더 많은 의도를 보여주고 더 읽기 쉬울 것이다.캡처는 여기서도 사용할 수 있으며, 이러한 방법으로 훨씬 쉽게 액세스할 수 있습니다.
Mockito 2.15로 테스트 완료
any(Class type) 메서드를 사용하여 varargs 파라미터로 전달되는 배열 arg를 일치시켜야 했습니다.
ArgumentMatchers.any(클래스 유형)
구현 내 코드는 vararg 인식입니다.
reportMatcher(새로운 InstanceOf).VarArgAware()
String [ ]arg를 String에 매칭하는 경우...param은 다음과 같이 동작합니다.-
any(String.class)
언급URL : https://stackoverflow.com/questions/2631596/how-to-properly-match-varargs-in-mockito
'itsource' 카테고리의 다른 글
MySQL Fast Select Query | C# 고속 로드 데이터 테이블 (0) | 2022.09.05 |
---|---|
1114(HY000):테이블이 꽉 찼다 (0) | 2022.09.05 |
if-elif-else 문구를 한 줄에 넣는 거? (0) | 2022.09.05 |
XAMPP에 MariaDB 또는 MySQL이 있습니까? (0) | 2022.09.05 |
Amazon EC2 인스턴스의 MariaDB에 원격으로 연결하는 데 문제가 있습니다. (0) | 2022.09.05 |