6

Можно ли с помощью Mockito захватывать аргументы метода, вызываемого несколько раз?

12

Я столкнулся с проблемой: у меня есть метод, который вызывается дважды, и мне нужно захватить аргумент второго вызова этого метода.

Вот что я попробовал:

ArgumentCaptor<Foo> firstFooCaptor = ArgumentCaptor.forClass(Foo.class);
ArgumentCaptor<Foo> secondFooCaptor = ArgumentCaptor.forClass(Foo.class);
verify(mockBar).doSomething(firstFooCaptor.capture());
verify(mockBar).doSomething(secondFooCaptor.capture());
// затем выполняю утверждения на secondFooCaptor.getValue()

Но я получаю исключение TooManyActualInvocations, так как Mockito считает, что doSomething должен быть вызван только один раз.

Как я могу проверить аргумент второго вызова метода doSomething?

3 ответ(ов)

0

Вы также можете использовать аннотированный @Captor ArgumentCaptor. Например:

@Mock
List<String> mockedList;

@Captor
ArgumentCaptor<String> argCaptor;

@BeforeTest
public void init() {
    // Инициализируем объекты, аннотированные @Mock, @Captor и @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));
}

В этом примере мы создаем мок-объект mockedList и используем @Captor для захвата аргументов, передаваемых в метод add. В методе теста shouldCallAddMethodTwice мы вызываем метод add дважды, а затем проверяем, что он был вызван именно с теми значениями, которые мы ожидаем. Использование argCaptor позволяет нам получить доступ к аргументам, переданным в мок-объект, что делает тестирование более удобным и наглядным.

0

С помощью лямбд в Java 8 удобно использовать следующий подход с Mockito:

import static org.mockito.Mockito.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

when(client.deleteByQuery(anyString(), anyString())).then(invocationOnMock -> {
    assertEquals("myCollection", invocationOnMock.getArgument(0));
    assertThat(invocationOnMock.getArgument(1), startsWith("id:"));
});

В этом примере мы используем метод when, чтобы задать поведение мок-объекта client. Мы передаем лямбд и используем invocationOnMock, чтобы получить аргументы, переданные в метод deleteByQuery. Затем мы проверяем, что первый аргумент равен "myCollection", а второй аргумент начинается с "id:". Этот подход позволяет гибко реагировать на вызовы методов с помощью моков и производить необходимые проверки аргументов.

0

Во-первых, вам всегда следует импортировать статические методы Mockito, так код будет гораздо более читаемым (и интуитивно понятным) — примеры кода ниже требуют этого для работы:

import static org.mockito.Mockito.*;

В методе verify() вы можете передать ArgumentCaptor, чтобы удостовериться в выполнении действия в тесте, а также использовать ArgumentCaptor для оценки аргументов:

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());
}

Список всех переданных аргументов во время вашего теста доступен через метод argument.getAllValues().

Значение единственного (последнего вызванного) аргумента можно получить с помощью argument.getValue(), чтобы использовать его для дальнейшей обработки, проверки или любых других нужд.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь