모키토:바운드가 있는 와일드카드를 사용하여 타입을 반환하는 스터브 방식
다음 코드를 고려하십시오.
public class DummyClass {
public List<? extends Number> dummyMethod() {
return new ArrayList<Integer>();
}
}
public class DummyClassTest {
public void testMockitoWithGenerics() {
DummyClass dummyClass = Mockito.mock(DummyClass.class);
List<? extends Number> someList = new ArrayList<Integer>();
Mockito.when(dummyClass.dummyMethod()).thenReturn(someList); //Compiler complains about this
}
}
컴파일러가 동작의 스텁을 시도하는 회선에 대해 불만을 제기합니다.dummyMethod()경계 와일드카드로 타입을 반환하는 스터브 메서드에 대한 힌트가 있습니까?
이 목적을 위해 non-type safe 메서드 doReturn을 사용할 수도 있습니다.
@Test
public void testMockitoWithGenerics()
{
DummyClass dummyClass = Mockito.mock(DummyClass.class);
List<? extends Number> someList = new ArrayList<Integer>();
Mockito.doReturn(someList).when(dummyClass).dummyMethod();
Assert.assertEquals(someList, dummyClass.dummyMethod());
}
모키토의 구글 그룹에서 논의된 바와 같이.
이것은 보다 심플하지만thenAnswer는 타입 세이프가 아님을 다시 한 번 주의해 주십시오.만약 당신이 타입의 안전이 걱정된다면, 밀하우스의 답변이 정확합니다.
기타 상세
확실히 하기 위해서, 여기 발견된 컴파일러 에러가 있습니다.
The method thenReturn(List<capture#1-of ? extends Number>) in the type OngoingStubbing<List<capture#1-of ? extends Number>> is not applicable for the arguments (List<capture#2-of ? extends Number>)
컴파일러가 첫 번째 와일드카드 유형을 할당했다고 생각합니다.when를 호출하고 나서, 다음의 와일드 카드 타입을 확인할 수 없습니다.thenReturncall은 동일합니다.
이 모양은thenAnswer이 문제는 발생하지 않습니다.왜냐하면 와일드카드 타입을 받아들이기 때문입니다.thenReturn는 캡처해야 하는 비패키지 타입을 취합니다.모키토의 '진행형 스터빙'에서
OngoingStubbing<T> thenAnswer(Answer<?> answer);
OngoingStubbing<T> thenReturn(T value);
내 생각엔 네가 짐을 싣고 싶어할 수 있을 것 같아.someList몇 가지 알려진 가치를 가지고 있습니다.여기에서는, 다음의 어프로치를 사용하고 있습니다.Answer<T>템플릿 도우미 방법과 함께 모든 것을 안전하게 유지합니다.
@Test
public void testMockitoWithGenericsUsingAnswer()
{
DummyClass dummyClass = Mockito.mock(DummyClass.class);
Answer<List<Integer>> answer = setupDummyListAnswer(77, 88, 99);
Mockito.when(dummyClass.dummyMethod()).thenAnswer(answer);
...
}
private <N extends Number> Answer<List<N>> setupDummyListAnswer(N... values) {
final List<N> someList = new ArrayList<N>();
someList.addAll(Arrays.asList(values));
Answer<List<N>> answer = new Answer<List<N>>() {
public List<N> answer(InvocationOnMock invocation) throws Throwable {
return someList;
}
};
return answer;
}
어제도 똑같은 걸 쳤어요.@nondescript1과 @millhouse의 답변은 모두 회피책을 찾는 데 도움이 되었습니다.저는 @millhouse와 거의 같은 코드를 사용하고 있습니다.단, 조금 더 일반적인 코드를 사용했다는 점만 빼면, 제 에러는 다음 에러가 아닙니다.java.util.List단,com.google.common.base.Optional따라서 나의 작은 도우미 방식은 모든 타입을 허용한다.T뿐만 아니라List<T>:
public static <T> Answer<T> createAnswer(final T value) {
Answer<T> dummy = new Answer<T>() {
@Override
public T answer(InvocationOnMock invocation) throws Throwable {
return value;
}
};
return dummy;
}
이 도우미 방법을 사용하면 다음과 같이 쓸 수 있습니다.
Mockito.when(dummyClass.dummyMethod()).thenAnswer(createAnswer(someList));
이것은 컴파일이 잘 되어 있고, 같은 기능을 합니다.thenReturn(...)방법.
Java 컴파일러에서 발생한 오류가 컴파일러 버그인지, 코드가 정말 잘못된 것인지 아는 사람이 있습니까?
Java 8+를 사용하는 가장 우아한 솔루션이라고 생각하기 때문에 보다 가시성을 높이기 위해 fikovnik의 코멘트를 답변으로 변환합니다.
Mockito 문서에서는 다음을 사용할 것을 권장합니다.doReturn()(허락된 답변에 제시된 바와 같이) 최후의 수단으로만 사용됩니다.
대신 질문에서 설명된 컴파일러 오류를 확인하기 위해 권장되는 Mockito는when()어프로치를 사용할 수 있다thenAnswer()및 람다(도움말 방법의 개요):
Mockito.when(mockedClass.mockedMethod()).thenAnswer(x -> resultList)
Marrek Radonsky가 제안한 유틸리티 방법은 효과가 있지만, (IMHO 기묘한 모습의) 람다 표현 fikovnik이 제안하지 않아도 되는 다른 옵션도 있습니다.
유사한 질문에 대한 이 답변에서 알 수 있듯이 다음 항목도 사용할 수 있습니다.
BDDMockito.willReturn(someList).given(dummyClass).dummyMethod();
언급URL : https://stackoverflow.com/questions/7366237/mockito-stubbing-methods-that-return-type-with-bounded-wild-cards
'source' 카테고리의 다른 글
| 문자열에서 마지막으로 발생한 문자열 바꾸기 (0) | 2022.10.06 |
|---|---|
| where 문이 있는 대량 업데이트 mysql (0) | 2022.10.06 |
| Python에서 텍스트 파일을 연결하려면 어떻게 해야 하나요? (0) | 2022.10.06 |
| Symfony 2 Entity Manager 주입 인 서비스 (0) | 2022.10.06 |
| 텍스트 파일에서 문자열을 검색하려면 어떻게 해야 합니까? (0) | 2022.10.06 |