Mockito는 여러 번 호출된 메서드의 인수를 캡처할 수 있습니까?
두 번 호출되는 메서드가 있는데 두 번째 메서드 호출 인수를 캡처하고 싶습니다.
제가 시도한 것은 다음과 같습니다.
ArgumentCaptor<Foo> firstFooCaptor = ArgumentCaptor.forClass(Foo.class);
ArgumentCaptor<Foo> secondFooCaptor = ArgumentCaptor.forClass(Foo.class);
verify(mockBar).doSomething(firstFooCaptor.capture());
verify(mockBar).doSomething(secondFooCaptor.capture());
// then do some assertions on secondFooCaptor.getValue()
하지만 난...TooManyActualInvocations
예외, 모키토가 생각하는 것처럼doSomething
한 번만 호출해야 합니다.
의 두 번째 콜 인수를 확인하려면 어떻게 해야 합니까?doSomething
?
그래야 할 것 같아요.
verify(mockBar, times(2)).doSomething(...)
mockito javadoc 샘플:
ArgumentCaptor<Person> peopleCaptor = ArgumentCaptor.forClass(Person.class);
verify(mock, times(2)).doSomething(peopleCaptor.capture());
List<Person> capturedPeople = peopleCaptor.getAllValues();
assertEquals("John", capturedPeople.get(0).getName());
assertEquals("Jane", capturedPeople.get(1).getName());
Mockito 2.0 이후 정적 메서드 Matchers.arg That(Argument Matcher)을 사용할 수도 있습니다.Java 8의 도움으로 보다 깔끔하고 읽기 쉽게 되었습니다.
verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("OneSurname")));
verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("AnotherSurname")));
Java 버전보다 낮은 버전을 사용해야 한다면, 그 정도도 나쁘지 않습니다.
verify(mockBar).doSth(argThat(new ArgumentMatcher<Employee>() {
@Override
public boolean matches(Object emp) {
return ((Employee) emp).getSurname().equals("SomeSurname");
}
}));
물론 이들 중 어느 것도 콜 순서를 확인할 수 없습니다.InOrder를 사용해야 합니다.
InOrder inOrder = inOrder(mockBar);
inOrder.verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("FirstSurname")));
inOrder.verify(mockBar).doSth(argThat((arg) -> arg.getSurname().equals("SecondSurname")));
다음과 같은 전화를 할 수 있는 mockito-java8 프로젝트를 봐주세요.
verify(mockBar).doSth(assertArg(arg -> assertThat(arg.getSurname()).isEqualTo("Surname")));
에의 모든 콜을 검증하고 싶지 않은 경우doSomething()
, 마지막 1개만 사용할 수 있습니다.ArgumentCaptor.getValue()
. Mockito javadoc에 따르면:
메서드가 여러 번 호출된 경우 마지막으로 캡처된 값이 반환됩니다.
이 방법은 유효합니다(전제:Foo
방법이 있다getName()
):
ArgumentCaptor<Foo> fooCaptor = ArgumentCaptor.forClass(Foo.class);
verify(mockBar, times(2)).doSomething(fooCaptor.capture());
//getValue() contains value set in second call to doSomething()
assertEquals("2nd one", fooCaptor.getValue().getName());
@Captor 주석이 달린 ArgumentCaptor를 사용할 수도 있습니다.예를 들어 다음과 같습니다.
@Mock
List<String> mockedList;
@Captor
ArgumentCaptor<String> argCaptor;
@BeforeTest
public void init() {
//Initialize objects annotated with @Mock, @Captor and @Spy.
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldCallAddMethodTwice() {
mockedList.add("one");
mockedList.add("two");
Mockito.verify(mockedList, times(2)).add(argCaptor.capture());
assertEquals("one", argCaptor.getAllValues().get(0));
assertEquals("two", argCaptor.getAllValues().get(1));
}
자바8의 람다와 함께, 편리한 방법은
org.mockito.invocation.InvocationOnMock
when(client.deleteByQuery(anyString(), anyString())).then(invocationOnMock -> {
assertEquals("myCollection", invocationOnMock.getArgument(0));
assertThat(invocationOnMock.getArgument(1), Matchers.startsWith("id:"));
}
우선, 항상 mockito static을 Import 해 주세요.이렇게 하면, 코드의 판독성이 향상해, 직감적으로 사용할 수 있습니다.아래의 코드 샘플에서는, 동작하기 위해서 필요합니다.
import static org.mockito.Mockito.*;
verify() 메서드에서는 Argument Captor를 전달하여 테스트 실행을 보증하고 Argument Captor를 전달하여 인수를 평가할 수 있습니다.
ArgumentCaptor<MyExampleClass> argument = ArgumentCaptor.forClass(MyExampleClass.class);
verify(yourmock, atleast(2)).myMethod(argument.capture());
List<MyExampleClass> passedArguments = argument.getAllValues();
for (MyExampleClass data : passedArguments){
//assertSometing ...
System.out.println(data.getFoo());
}
테스트 중에 전달된 모든 인수 목록은 인수.getAllValues() 메서드를 통해 액세스할 수 있습니다.
단일(마지막 호출된) 인수 값은 argument.getValue()를 통해 액세스할 수 있으며 추가 조작/체크 또는 원하는 작업을 수행할 수 있습니다.
언급URL : https://stackoverflow.com/questions/5981605/can-mockito-capture-arguments-of-a-method-called-multiple-times
'source' 카테고리의 다른 글
그룹화된 Panda 데이터 프레임을 어떻게 루프합니까? (0) | 2022.11.05 |
---|---|
블레이드 템플릿의 모든 HTML 이스케이프 Larabel (0) | 2022.11.05 |
예외를 발생시킨 예외 설명 및 스택 추적을 모두 문자열로 가져옵니다. (0) | 2022.11.05 |
QUERY 패킷을 보내는 중 오류 발생 (0) | 2022.11.05 |
레지스트리 키 '...'의 값은 '1.7'이지만 '1.6'은 필수입니다.Java 1.7이 설치되어 레지스트리가 이를 가리키고 있다. (0) | 2022.11.05 |