mockitos ArgumentCaptore를 사용하여 특정 유형의 목록을 캡처하는 방법이 있습니까? 작동하지 않습니다.
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);
답변
중첩 된 제네릭 문제는 @Captor 주석 으로 피할 수 있습니다 .
public class Test{
@Mock
private Service service;
@Captor
private ArgumentCaptor<ArrayList<SomeType>> captor;
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldDoStuffWithListValues() {
//...
verify(service).doStuff(captor.capture()));
}
}
답변
예, 이것은 일반적인 특정 문제가 아니라 모의 특유의 문제입니다.
에 대한 클래스 객체가 없으므로 ArrayList<SomeType>
해당 객체를을 (를) 요구하는 메서드에 형식적으로 전달할 수 없습니다 Class<ArrayList<SomeType>>
.
객체를 올바른 유형으로 캐스트 할 수 있습니다.
Class<ArrayList<SomeType>> listClass =
(Class<ArrayList<SomeType>>)(Class)ArrayList.class;
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(listClass);
이것은 안전하지 않은 캐스트에 대한 몇 가지 경고를 줄 것이다, 그리고 물론 당신의 ArgumentCaptor 정말 구별 할 수 ArrayList<SomeType>
와 ArrayList<AnotherType>
어쩌면 요소를 검사하지 않고.
(이것은 일반적인 제네릭 문제가 동안으로는와 유형 안전 문제에 대한 Mockito 특정 솔루션이, 다른 대답에 언급 @Captor
주석이. 그것은 여전히 구별 할 수 없습니다 ArrayList<SomeType>
와 ArrayList<OtherType>
.)
편집하다:
tenshi 의 의견 도 살펴보십시오 . 당신은에서 원래의 코드를 변경할 수 있습니다 파울로 Ebermann 이 (훨씬 더 간단)로
final ArgumentCaptor<List<SomeType>> listCaptor
= ArgumentCaptor.forClass((Class) List.class);
답변
오래된 자바 스타일 (비 유형의 안전한 제네릭) 의미를 두려워하지 않는 경우에도 작동하며 상당히 간단합니다.
ArgumentCaptor<List> argument = ArgumentCaptor.forClass(List.class);
verify(subject.method(argument.capture()); // run your code
List<SomeType> list = argument.getValue(); // first captured List, etc.
답변
List<String> mockedList = mock(List.class);
List<String> l = new ArrayList();
l.add("someElement");
mockedList.addAll(l);
ArgumentCaptor<List> argumentCaptor = ArgumentCaptor.forClass(List.class);
verify(mockedList).addAll(argumentCaptor.capture());
List<String> capturedArgument = argumentCaptor.<List<String>>getValue();
assertThat(capturedArgument, hasItem("someElement"));
답변
@tenshi와 @pkalinow의 의견 (@rogerdpack에 대한 의견)을 바탕으로 다음은 “확인되지 않거나 안전하지 않은 작업 사용” 경고를 비활성화하는 목록 인수 캡처자를 만드는 간단한 솔루션입니다 .
@SuppressWarnings("unchecked")
final ArgumentCaptor<List<SomeType>> someTypeListArgumentCaptor =
ArgumentCaptor.forClass(List.class);
여기에 전체 예제 와 해당하는 전달 CI 빌드 및 테스트 실행이 있습니다 .
우리 팀은 단위 테스트에서 한동안 이것을 사용해 왔으며 이것은 우리에게 가장 간단한 해결책처럼 보입니다.
답변
이전 버전의 junit의 경우 다음을 수행 할 수 있습니다.
Class<Map<String, String>> mapClass = (Class) Map.class;
ArgumentCaptor<Map<String, String>> mapCaptor = ArgumentCaptor.forClass(mapClass);
답변
내 Android 앱에서 테스트 활동과 동일한 문제가 발생했습니다. 나는 사용 ActivityInstrumentationTestCase2
하고 MockitoAnnotations.initMocks(this);
작동하지 않았다. 각 필드가있는 다른 클래스 로이 문제를 해결했습니다. 예를 들면 다음과 같습니다.
class CaptorHolder {
@Captor
ArgumentCaptor<Callback<AuthResponse>> captor;
public CaptorHolder() {
MockitoAnnotations.initMocks(this);
}
}
그런 다음 활동 테스트 방법에서 :
HubstaffService hubstaffService = mock(HubstaffService.class);
fragment.setHubstaffService(hubstaffService);
CaptorHolder captorHolder = new CaptorHolder();
ArgumentCaptor<Callback<AuthResponse>> captor = captorHolder.captor;
onView(withId(R.id.signInBtn))
.perform(click());
verify(hubstaffService).authorize(anyString(), anyString(), captor.capture());
Callback<AuthResponse> callback = captor.getValue();