Mockito: Stubbing Методы, Которые Возвращают Тип С Ограниченными Дикими Картами
рассмотрим этот код:
public class DummyClass {
public List<? extends Number> dummyMethod() {
return new ArrayList<Integer>();
}
}
public class DummyClassTest {
public void testMockitoWithGenerics() {
DummyClass dummyClass = Mockito.mock(DummyClass.class);
List<? extends Number> someList = new ArrayList<Integer>();
Mockito.when(dummyClass.dummyMethod()).thenReturn(someList); //Compiler complains about this
}
}
компилятор жалуется на строку, которая пытается заглушить поведение для dummyMethod()
. Любые указатели на то, как можно использовать методы stubbing, которые возвращают тип с ограниченными дикими картами?
4 ответа:
вы также можете использовать не-тип безопасный метод doReturn С этой целью
@Test public void testMockitoWithGenerics() { DummyClass dummyClass = Mockito.mock(DummyClass.class); List<? extends Number> someList = new ArrayList<Integer>(); Mockito.doReturn(someList).when(dummyClass).dummyMethod(); Assert.assertEquals(someList, dummyClass.dummyMethod()); }
как обсуждали в группе google Mockito.
хотя это проще, чем
thenAnswer
, снова обратите внимание, что это не типобезопасно. Если вы беспокоитесь о безопасности типа, millhouse ответ является правильным.Дополнительная Информация
чтобы быть ясным, вот наблюдаемая ошибка компилятора,
метод thenReturn (List
) в типе OngoingStubbing > не применимо для Аргументов (List
) Я считаю, что компилятор назначил первый тип подстановочного знака во время
when
вызов, а затем не может подтвердить, что второй тип подстановочного знака вthenReturn
вызов тот же.похоже
thenAnswer
не сталкивается с этой проблемой, потому что он принимает подстановочный знак типа whilethenReturn
принимает тип без подстановочных знаков, который должен быть захвачен. От Мокито OngoingStubbing,OngoingStubbing<T> thenAnswer(Answer<?> answer); OngoingStubbing<T> thenReturn(T value);
Я предполагаю, что вы хотите быть в состоянии загрузить до
someList
С некоторыми известными значениями; вот подход, который используетAnswer<T>
вместе с шаблонным вспомогательным методом, чтобы сохранить все типобезопасным:@Test public void testMockitoWithGenericsUsingAnswer() { DummyClass dummyClass = Mockito.mock(DummyClass.class); Answer<List<Integer>> answer = setupDummyListAnswer(77, 88, 99); Mockito.when(dummyClass.dummyMethod()).thenAnswer(answer); ... } private <N extends Number> Answer<List<N>> setupDummyListAnswer(N... values) { final List<N> someList = new ArrayList<N>(); someList.addAll(Arrays.asList(values)); Answer<List<N>> answer = new Answer<List<N>>() { public List<N> answer(InvocationOnMock invocation) throws Throwable { return someList; } }; return answer; }
Я ударил то же самое вчера. Оба ответа от @nondescript1 и @millhouse помогли мне найти обходной путь. Я в значительной степени использовал тот же код, что и @millhouse, за исключением того, что я сделал его немного более общим, потому что моя ошибка не была вызвана
java.util.List
, аcom.google.common.base.Optional
. Поэтому мой маленький вспомогательный метод позволяет использовать любой типT
и не толькоList<T>
:public static <T> Answer<T> createAnswer(final T value) { Answer<T> dummy = new Answer<T>() { @Override public T answer(InvocationOnMock invocation) throws Throwable { return value; } }; return dummy; }
С помощью этого вспомогательного метода вы можете написать:
Mockito.when(dummyClass.dummyMethod()).thenAnswer(createAnswer(someList));
это компилируется просто замечательно и делает то же самое, что и
thenReturn(...)
метод.кто-нибудь знает, является ли ошибка, которую выдает компилятор Java, ошибкой компилятора или если код действительно неверен?
хотя метод полезности, предложенный Мареком Радонским, работает, есть и другой вариант, который даже не требует (имхо странного вида) лямбда-выражения, предложенного фиковником:
Как ответ к подобным шоу вопроса, Вы можете также использовать следующее:
BDDMockito.willReturn(someList).given(dummyClass).dummyMethod();