반응형
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
Mockito 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.argThat (ArgumentMatcher) 를 사용할 수도 있습니다 . 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()
마지막 호출 만 확인하면됩니다 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));
}
Java 8의 람다에서 편리한 방법은
org.mockito.invocation.InvocationOnMock
when(client.deleteByQuery(anyString(), anyString())).then(invocationOnMock -> {
assertEquals("myCollection", invocationOnMock.getArgument(0));
assertThat(invocationOnMock.getArgument(1), Matchers.startsWith("id:"));
}
반응형
'Programming' 카테고리의 다른 글
파이썬에서 다른 파일에서 함수 호출 (0) | 2020.02.22 |
---|---|
Swift 클래스의 정적 및 클래스 함수 / 변수? (0) | 2020.02.22 |
Go에서 두 조각을 연결 (0) | 2020.02.22 |
android : onClick XML 속성이 setOnClickListener와 정확히 어떻게 다릅니 까? (0) | 2020.02.22 |
SQL Server에서 INSERT INTO로 데이터 내보내기 (0) | 2020.02.22 |