Проверка, был ли метод вызван с определенными аргументами только один раз с mockito - PullRequest
3 голосов
/ 03 мая 2019

Я использую Mockito в kotlin, чтобы проверить, что список перемещен правильно

Я использую этот код

    logic.searchItems(filter)
    verify(vm).setItems(all.subList(0, 10), true)
    logic.loadNext()
    verify(vm).setItems(all.subList(0, 20), true)     (1)
    logic.loadNext()
    verify(vm).setItems(all.subList(0, 30), true)     (2)

Теоретически это должно работать, но я получаю слишком много исключений вызовов в (1) и (2).

Если я использую времена (1) в (1) и времена (2) в (2), тест проходит успешно. Но я хочу убедиться, что этот метод вызывается с этими конкретными аргументами.

Можно ли это сделать с помощью Mockito?

Ответы [ 2 ]

0 голосов
/ 03 мая 2019

С такими параметрами, являющимися коллекцией с определенным содержимым, я бы посоветовал использовать функцию ArgumentCaptor.Благодаря этому вы сможете захватывать переданные параметры и позже утверждать их значение / состояние, используя такие инструменты, как Hamcrest или AssertJ:

final ArgumentCaptor<List> captorListOne = ArgumentCaptor.forClass(List.class);
final ArgumentCaptor<List> captorListTwo = ArgumentCaptor.forClass(List.class);
final ArgumentCaptor<List> captorListThree = ArgumentCaptor.forClass(List.class);

verify(vm).setItems(captorListOne.capture(), true)
logic.loadNext()
verify(vm).setItems(captorListTwo.capture(), true)     
logic.loadNext()
verify(vm).setItems(captorListThree.capture(), true) 

List listToAssert = captorListOne.getValue();
...

Подробнее ArgumentCaptor

0 голосов
/ 03 мая 2019

После некоторого тестирования я понял, что проблема в том, что в моей логике я добавил результаты в тот же список, прежде чем отправить их обратно следующим образом:

addItems(results:List<Item>()){
    //verifications here
    myItems.addAll(results)
    vm.setItems(myItems,true)
}

это почему-то заставило мокито думать, что это был тот же самый вызов?

когда я так делаю, это работает

addItems(results:List<Item>()){
    //verifications here
    myItems.addAll(results)
    vm.setItems(myItems.map { it.copy() },true)
}

Я не знаю, является ли это ошибкой или предполагаемым поведением, но по крайней мере это работает

редактирование:

Хорошо, я чувствую себя идиотом, потому что это совсем не ошибка, это действительно предполагаемое поведение, и это спасло меня от некоторых будущих проблем

при использовании захватчиков я выяснил, что при вызове метода setItems Mockito сохраняет ссылку на возвращаемый список.

при следующем вызове я использовал для добавления элементов в myItems, а Mockito сохранил новую ссылку

но поскольку я выполнил операцию addAll, ранее сохраненная ссылка также была обновлена, поэтому вполне нормально, что Mockito нуждается в методе times (2) при его вызове, потому что список, который он получил в первом вызове, был обновляется и будет соответствовать второму списку.

кажется, что правильно отправить копию этого списка, таким образом viewModel не может каким-либо образом изменить исходный список

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...