Динамическое связывание, затем возврат в mockito

У меня есть фиктивный класс Tuple, методы getString (0) и getString (1) которого, как ожидается, будут вызываться n раз. Вместо того, чтобы писать что-то вроде,

when(tuple.getString(0)).thenReturn(logEntries[0]).thenReturn(logEntries[1])...thenReturn(logEntries[n - 1])

вручную я пробовал следующее:

OngoingStubbing stubbingGetStringZero = when(tuple.getString(0)).thenReturn(serviceRequestKey);
OngoingStubbing stubbingGetStringOne = when(tuple.getString(1)).thenReturn(logEntries[0]);
for (int i = 1; i < n; i++) {
    stubbingGetStringZero = stubbingGetStringZero.thenReturn(serviceRequestKey);
    stubbingGetStringOne = stubbingGetStringOne.thenReturn(logEntries[i]);
}

Ожидаемый результат состоит в том, что все вызовы tuple.getString(0) должны возвращать String serviceRequestKey, а каждый вызов tuple.getString(1) должен возвращать другую String logEntries[i], т.е. i-й вызов кортежа. getString (1) возвращает i-й элемент массива logEntries.

Однако по какой-то странной причине все смешалось, и второй вызов tuple.getString(1) возвращает String serviceRequestKey вместо logEntries[1]. Что мне здесь не хватает?


person gjain    schedule 29.07.2014    source источник


Ответы (4)


Что ж, правильный способ сделать это:

import org.mockito.AdditionalAnswers;

String[] logEntry = // Some initialization code
List<String> logEntryList = Arrays.asList(logEntry);
when(tuple.getString(1)).thenAnswer(AdditionalAnswers.returnsElementsOf(logEntryList));

При каждом вызове возвращаются последовательные элементы массива logEntry. Таким образом, i-й вызов tuple.getString(1) возвращает i-й элемент массива logEntry.

PS: Пример в документации returnElementsOf (на момент написания) не обновлен (он все еще использует пример ReturnsElementsOf): http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/AdditionalAnswers.html#returnsElementsOf(java.util.Collection)it

person gjain    schedule 29.07.2014

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

Mockito.when(tuple.getString(0)).thenReturn(serviceRequestKey,logEntries[0],logEntries[1])

При этом вы получите serviceRequestKey при первом вызове, logEntries [0] при втором и т. Д.

Если вам нужно что-то более сложное, например, изменить возврат в зависимости от параметра в методе, используйте thenAnswer (), как показано здесь

person Nadir    schedule 29.07.2014
comment
Что ж, ваш ответ правильный и по сути является сокращенной версией множественного thenReturn. Единственное, что количество вызовов в моем случае немного великовато ~ 15-20. Итак, мне придется написать столько параметров для thenReturn. Надеялся найти решение, используя цикл for или что-то в этом роде. - person gjain; 29.07.2014
comment
Метод thenReturn принимает String [], поэтому вы можете создать массив в цикле по своему усмотрению и затем передать его. - person Nadir; 29.07.2014
comment
thenReturn () принимает только несколько параметров String, а не массив. См .: docs.mockito.googlecode.com/hg/org/ mockito / stubbing /. В любом случае, ваш комментарий помог мне посмотреть в правильном направлении. Спасибо! - person gjain; 29.07.2014
comment
@gjain, varargs - это просто синтаксический сахар поверх массивов, поэтому String [] будет работать хорошо. См. stackoverflow.com/questions/2925153/ для получения дополнительных сведений. - person Mikael Ohlson; 19.03.2015
comment
@MikaelOhlson Проблема в том, что вам нужно пройти долгую прогулку с синтаксисом Mockito, потому что вам нужно вырезать первый аргумент из массива, чтобы он соответствовал: thenReturn (T value, T ... values), затем subList, и это беспорядок. - person deworde; 07.05.2015

Не уверен, что я достаточно хорошо понимаю Mockito, чтобы понять ваш пример, но разве вам не нужно что-то вроде:

Mockito.when(tuple.getString(0)).thenReturn(serviceRequestKey);
for(int i = 0;i < logEntries.length;i++) {
    Mockito.when(tuple.getString(i+1)).thenReturn(logEntries[i]);
}
person The F    schedule 29.07.2014
comment
Я уточнил вопрос дальше. На самом деле, я хочу получить разные результаты от каждого вызова tuple.getString (1). Обратите внимание, что это всегда tuple.getString (1), индекс не меняется. - person gjain; 29.07.2014

Я знаю, что этот пост старше, но, возможно, он помогает:

    OngoingStubbing<Boolean> whenCollectionHasNext = when(mockCollectionStream.hasNext());
    for (int i = 0; i < 2; i++) {
        whenCollectionHasNext = whenCollectionHasNext.thenReturn(true);
    }
    whenCollectionHasNext = whenCollectionHasNext.thenReturn(false);
person Michael Hegner    schedule 27.06.2017
comment
Это не работает. Вот сообщение об ошибке: Вы, вероятно, сохранили ссылку на OngoingStubbing, возвращаемую функцией when (), и неоднократно вызывали методы заглушки, такие как thenReturn (), для этой ссылки. - person Younes EO; 09.12.2019