mockito 콜백 및 인수 값 가져 오기


88

함수 인수 값을 캡처하기 위해 Mockito를 얻는 운이 없습니다! 검색 엔진 색인을 조롱하고 색인을 작성하는 대신 해시를 사용하고 있습니다.

// Fake index for solr
Hashmap<Integer,Document> fakeIndex;

// Add a document 666 to the fakeIndex
SolrIndexReader reader = Mockito.mock(SolrIndexReader.class);

// Give the reader access to the fake index
Mockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))

쿼리 결과 (즉, 반환하는 문서)를 테스트하기 때문에 임의의 인수를 사용할 수 없습니다. 마찬가지로, 특정 값을 지정하고 각 문서에 대한 행을 갖고 싶지 않습니다!

Mockito.when(reader.document(0)).thenReturn(document(fakeIndex(0))
Mockito.when(reader.document(1)).thenReturn(document(fakeIndex(1))
....
Mockito.when(reader.document(n)).thenReturn(document(fakeIndex(n))

Using Mockito 페이지 의 콜백 섹션을 살펴 보았습니다 . 불행히도 Java가 아니며 Java에서 작동하도록 자체 해석을 얻을 수 없습니다.

편집 (설명을 위해) : Mockito가 인수 X를 캡처하여 내 함수에 전달하도록하려면 어떻게해야합니까? 함수에 전달 된 X의 정확한 값 (또는 참조)을 원합니다.

모든 경우를 열거하고 싶지는 않으며 다른 쿼리에 대해 다른 결과를 테스트하기 때문에 임의의 인수가 작동하지 않습니다.

Mockito 페이지에는

val mockedList = mock[List[String]]
mockedList.get(anyInt) answers { i => "The parameter is " + i.toString } 

그것은 자바가 아니고 자바로 번역하거나 무슨 일이 일어 났는지 함수로 전달하는 방법을 모릅니다.


나는 당신에게 무엇이 실패했는지 정확히 이해하지 못합니다. 에 대한 호출 Mockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))은 모의 객체를 설정해야합니다. 전화하면 reader.document(666)어떻게 되나요?
highlycaffeinated

666은 잘 작동합니다. 그러나 특정 숫자 X를 전달하고 fakeIndex (X)의 결과를 얻고 싶습니다. 쿼리를 테스트 할 잠재적 인 문서가 많고 모두 입력하고 싶지 않습니다.
nflacco 2011

답변:


103

저는 Mockito를 사용 해본 적이 없지만 배우고 싶어요. 나보다 잘 모르는 사람이 대답하면 먼저 대답 해보세요!

Mockito.when(reader.document(anyInt())).thenAnswer(new Answer() {
 public Object answer(InvocationOnMock invocation) {
     Object[] args = invocation.getArguments();
     Object mock = invocation.getMock();
     return document(fakeIndex((int)(Integer)args[0]));
     }
 });

2
난 단지에 오른쪽에있는 링크를 발견 어떻게 방법이 자신에게 전달 된 인수를 반환하게하는 방법 : Mockito를 . 내가 가까이 있지 않다면 가까운 것 같습니다.
Ed Staub 2011

강한 사용자 평판 (666)과 원래의 질문 상관 관계! 아주 잘 작동했습니다. 만 .... 내가 물건 컴파일을 얻기 위해 만든 개체 대답 (InvocationOnMock 호출)의 앞에 대중을 넣어 변경
nflacco

54

ArgumentCaptors를 확인하십시오.

https://site.mockito.org/javadoc/current/org/mockito/ArgumentCaptor.html

ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
Mockito.when(reader.document(argument.capture())).thenAnswer(
  new Answer() {
    Object answer(InvocationOnMock invocation) {
      return document(argument.getValue());
    }
  });

3
와, ArgumentCaptors를 스터 빙에 사용할 수 있는지 몰랐습니다 . 그래도 그 링크에 그것에 대한 큰 경고가 있습니다. 조심해서 진행해라.
einnocent

3
네, 맞아요. 캡터는 확인에만 사용해야합니다.
qualidafial

41

ArgumentCaptor와 함께 verify ()를 사용하여 테스트에서 실행을 보장하고 ArgumentCaptor를 사용하여 인수를 평가할 수 있습니다.

ArgumentCaptor<Document> argument = ArgumentCaptor.forClass(Document.class);
verify(reader).document(argument.capture());
assertEquals(*expected value here*, argument.getValue());

인수의 값은 추가 조작 / 검사 또는 원하는 작업을 위해 argument.getValue ()를 통해 분명히 액세스 할 수 있습니다.


2
가장 좋은 대답 : 정직은 쉽게 이해하기
라두 Cugut에게

질문에 대답하지 않습니다. 질문은 Mockito에 관한 것입니다.
seBaka28

@ seBaka28 인수를 얻는 가장 좋은 솔루션은 인수 캡처 자입니다. ArgumentCaptors는 Mockito 작성자의 검증과 함께 사용하는 것이 좋습니다. 따라서 완전한 관점에 대한 답변을 제공하고 싶었습니다. 당신이 그들을 사용하지 않기로 선택했다면 그것은 당신의 선택이지만 권장되지는 않습니다. 편집 : 이것이 어떻게 반대표를 정당화하는지 보지 못하지만 그것은 또한 당신의 선택입니다.
fl0w

1
질문에 답하지 않기 때문입니다. 예, ArgumentCaptor는 인수를 캡처하고 싶을 때 훌륭하지만 OP가 수행하려는 작업 인 when (...). thenReturn ()과 함께 사용할 수 없습니다. 특정 매개 변수를 기반으로하는 모의 서비스 특정 객체를 반환해야합니다.
seBaka28

1
@YuraHoy는 verify를 사용할 때 표준 오류 메시지이며 개체 또는 메서드가 verify에서 예상 한 것보다 더 자주 호출됩니다. 다음과 같이 times (n) 인수를 추가하여 예상 횟수를 변경할 수 있습니다. verify (reader, times (5))-5 개의 상호 작용이 예상됩니다. 참조 : baeldung.com/mockito-verify
fl0w

13

Java 8에서는 다음과 같을 수 있습니다.

Mockito.when(reader.document(anyInt())).thenAnswer(
  (InvocationOnMock invocation) -> document(invocation.getArguments()[0]));

나는 그것이 document지도 라고 가정하고있다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.