Создайте посмеянный список mockito
Я хочу создать посмеянный список для проверки кода ниже:
for (String history : list) {
//code here
}
Вот моя реализация:
public static List<String> createList(List<String> mockedList) {
List<String> list = mock(List.class);
Iterator<String> iterHistory = mock(Iterator.class);
OngoingStubbing<Boolean> osBoolean = when(iterHistory.hasNext());
OngoingStubbing<String> osHistory = when(iterHistory.next());
for (String history : mockedList) {
osBoolean = osBoolean.thenReturn(true);
osHistory = osHistory.thenReturn(history);
}
osBoolean = osBoolean.thenReturn(false);
when(list.iterator()).thenReturn(iterHistory);
return list;
}
Но при запуске теста он генерирует исключение в строке:
OngoingStubbing<DyActionHistory> osHistory = when(iterHistory.next());
для деталей:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at org.powermock.api.mockito.PowerMockito.when(PowerMockito.java:495)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
Как я могу это исправить? Благодаря
Ответы
Ответ 1
Хорошо, это плохо. Не издевайтесь над списком; вместо этого издеваются над отдельными объектами внутри списка. См. Mockito: высмеивает arraylist, который будет зациклен в цикле for для того, как это сделать.
Кроме того, почему вы используете PowerMock? Кажется, вы не делаете ничего, что требует PowerMock.
Но реальная причина вашей проблемы заключается в том, что вы используете when
на двух разных объектах, прежде чем завершить завершение. Когда вы вызываете when
и предоставляете вызов метода, который вы пытаетесь заглушить, то следующая вещь, которую вы делаете в Mockito или PowerMock, заключается в том, чтобы указать, что происходит, когда этот метод вызывается, т.е. Делать thenReturn
часть. Каждый вызов when
должен сопровождаться одним и только одним вызовом thenReturn
, прежде чем вы сделаете больше вызовов when
. Вы сделали два вызова when
без вызова thenReturn
- этой ошибки.
Ответ 2
Когда мы имеем дело с издевательскими списками и итерацией их, я всегда использую что-то вроде:
@Spy
private List<Object> parts = new ArrayList<>();
Ответ 3
Мы можем правильно составить список для цикла foreach. Ниже приведен фрагмент кода и пояснения.
Это мой метод фактического класса, в котором я хочу создать тестовый пример из-за насмешливого списка.
this.nameList
- это объект списка.
public void setOptions(){
// ....
for (String str : this.nameList) {
str = "-"+str;
}
// ....
}
Цикл foreach внутренне работает на итераторе, поэтому здесь мы разбиваем макет итератора.
В структуре Mockito есть возможность вернуть пару значений для конкретного вызова метода с помощью Mockito.when().thenReturn()
, то есть на hasNext()
мы передаем 1-е истинное значение, а во втором - false, чтобы наш цикл продолжался всего два раза. На next()
мы возвращаем фактическое возвращаемое значение.
@Test
public void testSetOptions(){
// ...
Iterator<SampleFilter> itr = Mockito.mock(Iterator.class);
Mockito.when(itr.hasNext()).thenReturn(true, false);
Mockito.when(itr.next()).thenReturn(Mockito.any(String.class);
List mockNameList = Mockito.mock(List.class);
Mockito.when(mockNameList.iterator()).thenReturn(itr);
// ...
}
Таким образом, мы можем избежать отправки фактического списка для проверки, используя макет списка.