[java] 스터 빙에 ArgumentCaptor를 사용하는 방법은 무엇입니까?

Mockito 문서javadocs 에 따르면

검증에는 사용하지만 스터 빙에는 사용하지 않는 ArgumentCaptor를 사용하는 것이 좋습니다.

그러나 ArgumentCaptor를 스터 빙에 사용하는 방법을 이해하지 못합니다. 누군가 위의 설명을 설명하고 ArgumentCaptor를 스터 빙에 사용하는 방법을 보여 주거나 수행 방법을 보여주는 링크를 제공 할 수 있습니까?



답변

테스트 할 다음 방법을 가정합니다.

public boolean doSomething(SomeClass arg);

Mockito 문서에 따르면 다음과 같이 captor를 사용 해서는 안됩니다 .

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);
assertThat(argumentCaptor.getValue(), equalTo(expected));

스터 빙 중 매처를 사용할 수 있기 때문에 :

when(someObject.doSomething(eq(expected))).thenReturn(true);

그러나 검증은 다른 이야기입니다. 테스트에서이 메소드가 특정 인수와 함께 호출되었는지 확인해야하는 ArgumentCaptor경우이를 사용하십시오.

ArgumentCaptor<SomeClass> argumentCaptor = ArgumentCaptor.forClass(SomeClass.class);
verify(someObject).doSomething(argumentCaptor.capture());
assertThat(argumentCaptor.getValue(), equalTo(expected));


답변

라인

when(someObject.doSomething(argumentCaptor.capture())).thenReturn(true);

~와 같은 일을 할 것이다

when(someObject.doSomething(Matchers.any())).thenReturn(true);

따라서 스터 빙에 값이 추가되지 않은 경우 argumentCaptor.capture ()를 사용하십시오. Matchers.any ()를 사용하면 실제로 발생하는 상황이 더 잘 나타나므로 가독성이 향상됩니다. argumentCaptor.capture ()를 사용하면 실제로 일치하는 인수를 읽을 수 없습니다. 그리고 any ()를 사용하는 대신 테스트를 개선하기 위해 더 많은 정보 (예상 인수의 클래스)가있을 때 더 구체적인 매처를 사용할 수 있습니다.

그리고 또 다른 문제 : 스터 빙 할 때 argumentCaptor.capture ()를 사용하면 확인 후 캡처해야 할 값이 명확하지 않습니다. 그 시점에는 아직 캡처 할 값이 없기 때문에 스터 빙 중에가 아닌 검증 중에 값을 캡처하려고합니다. 그렇다면 인수 캡터는 스터 빙 중에 메소드 캡처를 무엇으로 캡처합니까? 아니면 아무것도 포착하지 않습니까? 이 질문에 대한 답변이 없습니다. 정의되지 않은 동작으로 간주하고 정의되지 않은 동작을 사용하고 싶지 않습니다.


답변

가설로 검색이이 질문에 착륙했다면 아마도 이것을 원할 것입니다.

doReturn(someReturn).when(someObject).doSomething(argThat(argument -> argument.getName().equals("Bob")));

왜? 나처럼 당신은 시간을 소중히 .equals여기며 단일 테스트 시나리오를 위해서만 구현하지 않을 것 입니다.

그리고 테스트의 99 %는 Mock에서 null을 반환하여 분리되며 합리적인 디자인 null으로 모든 비용, 반환 Optional또는 Kotlin으로의 이동을 피할 수 있습니다 . 이것은 verify종종 자주 사용될 필요가 없으며 ArgumentCaptors는 너무 지루합니다.


답변