Mockito:返回带有有界通配符的类型

请考虑以下代码:

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


答案 1

您也可以使用非类型安全方法 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());
}

正如Mockito的谷歌小组中讨论的那样。

虽然这比 简单,但再次注意它不是类型安全的。如果你担心类型安全,Millhouse的答案是正确的。thenAnswer

其他详细信息

需要明确的是,这是观察到的编译器错误,

The method thenReturn(List<capture#1-of ? extends Number>) in the type OngoingStubbing<List<capture#1-of ? extends Number>> is not applicable for the arguments (List<capture#2-of ? extends Number>)

我相信编译器在调用期间分配了第一个通配符类型,然后无法确认调用中的第二个通配符类型是否相同。whenthenReturn

它似乎没有遇到此问题,因为它接受通配符类型,而采用非通配符类型,必须捕获。从Mockito的ConsingStubbingthenAnswerthenReturn

OngoingStubbing<T> thenAnswer(Answer<?> answer);
OngoingStubbing<T> thenReturn(T value);

答案 2

我假设您希望能够加载一些已知值;下面是一种与模板化帮助程序方法一起使用的方法,以确保所有内容的类型安全:someListAnswer<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;
}

推荐