지우기 유형 때문에 Mockito는 someMock.someMethod
에 전달되는 SomeInterface<T>
인스턴스의 일반 매개 변수를 런타임에 확인할 수 없습니다. someMethod
에 대한 모든 호출은 일반 매개 변수없이 SomeInterface
의 인스턴스로 작성된 것으로 보입니다.
(는 이유는 설명하지 않지만) Matchers를위한 JavaDoc는 경고와 함께이 문제를 암시 :
을 방법은 모든 종류의 검사하지 않는, 사람들은 여기있는 모든 가족 귀하의 코드에서 캐스팅을 피하십시오. 유형 검사를 수행하려면 isA (Class) 메소드를 사용하십시오. 그러나 향후 주요 릴리스에서이 유형이 변경 될 수 있습니다 (유형 점검이 추가 될 수 있음).
이 컬렉션의 일반 매개 변수를 처리하는 것 anyListOf
같은 다른 헬퍼 방법은, 그러나 다시이 단지 편의를 위해 존재하고, 실제로 제네릭 형식 확인하지 않습니다 : 친화적 인
일반을 anyList()에 대한 별명. @SuppressWarnings ("unchecked") 대신 컴파일러 경고 코드에서 코드를 깨끗하게 유지할 수 있습니다.
모든 목록 또는 null.
이 방법 은 어떤 종류의 검사도하지 않으므로, 코드에 캐스팅하지 않는 것이 좋습니다. 그러나 향후 주요 릴리스에서이 유형이 변경 될 수 있습니다 (유형 점검이 추가 될 수 있음). any()
정규 관계없이 유형 및 일반 매개 변수의 객체를 일치하기 때문에
, any()
와 when()
에 두 번째 호출은 첫 번째보다 우선합니다. 이 문제에 대한 유일한 해결책은 호출 유형 모두에 대해 when(...)
을 한 번만 호출하고 어떤 종류의 런타임 검사를 수행하여 결과가 무엇인지 결정하는 것입니다 (예 : Answer
이 thenAnswer
으로 전달 된 경우).
예를 들어, 우리는 다음 클래스 조롱 할 생각 (조롱 정말 가치가 없다, 그러나 나와 함께 곰) :
public class SomeClass {
public <T> T getFirst(List<T> list) {
return list.get(0);
}
}
getFirst
방법은 클래스와 같은 문제가, any
을 사용하는 등/isA
/anyList
/anyListOf
정규 표현식 List<String>
과 List<Integer>
을 구분할 수 없습니다. 여기
는
andAnswer
이것을 조롱 한 가지 방법입니다 :
@Test
public void testGetFirst() {
SomeClass mock = mock(SomeClass.class);
when(mock.getFirst(Matchers.<List<?>>any())).thenAnswer(new Answer<Object>() {
@Override
public Object answer(InvocationOnMock invocation) {
List<?> list = (List<?>) invocation.getArguments()[0];
// Inspect the contents of the list to know which type to return
Object first = list.get(0);
if (first instanceof String) {
return "Z";
} else if (first instanceof Integer) {
return 1000;
} else {
return null;
}
}
});
String firstString = mock.getFirst(Arrays.asList("A", "B", "C"));
System.out.println(firstString); // prints Z
Integer firstInteger = mock.getFirst(Arrays.asList(1, 2, 3));
System.out.println(firstInteger); // prints 1000
}
이 꽤 못생긴, 그리고 그것을 실제 일반적인 유형의 사용 방법에 따라 달성하기 매우 어려울 수 있지만, 나는 그것이 믿는다 런타임시 제네릭 형식 정보의 부족을 해결할 수있는 유일한 방법입니다.