需要解释:避免转换的通用友好性,这在Java 8中不再需要


* @deprecated With Java 8 this method will be removed in Mockito 3.0. This method is only used for generic
 * friendliness to avoid casting, this is not anymore needed in Java 8.
 */
public static <T> List<T> anyListOf(Class<T> clazz) {
    return anyList();
}

我正在研究 Mockito 源代码并遇到了这个不推荐使用的方法,任何人都可以解释一下在 Java 8 中如何处理它。关于如何在不使用此方法作为参数的情况下调用泛型方法的示例将不胜感激。

@Test
public void getDataTest() {
    when(dataSetDao.getDataSetList()).thenReturn(getMockDataSetList());
    when(serviceUtil.getDataFromEndpoint(anyInt(), anyList(), anyString(), any(TypeToken.class), anyString())).thenReturn(getMockDataList());
    List<Data> dataList = noaaDataService.getData();
    verify(serviceUtil, times(11)).getDataFromEndpoint(anyInt(), anyList(), anyString(), any(TypeToken.class), anyString());
    assertEquals(11, dataList.size());
}
private <T> List<T> getMockDataList() {
    List<Data> dataList = new ArrayList<>();
    for (int i = 0; i < 1; ++i) {
        dataList.add(new Data());
    }
    return (List<T>) dataList;
}

无法解析方法 'thenReturn(java.util.List(。这是我以上述方式调用该方法时收到的错误。

有人可以解释一下,如果在 Java 8 中改进了类型推断,为什么我会收到此错误。

调用的方法:

/**
 * Generic method to fetch data from rest endpoint.
 *
 * @param offset       Default should be 0, recursive call in place would increase it till we have fetched all the records.
 * @param dataList     List to be returned and passed on to the recursive call.
 * @param postFixUrl   End point to be used.
 * @param responseType Used to convert the response into json, need this so that we will know the generic type at compile time.
 * @param <T>          Entity for which we are fetching the data.
 * @param arguments    Arguments to be passed to the uri.
 * @return A list of T derived from the response.
 */
public <T> List<T> getDataFromEndpoint(
    int offset, List<T> dataList, String postFixUrl,
    TypeToken<ArrayList<T>> responseType, String arguments)

临时修复以解决此问题,有没有更好的方法可以做到这一点。

@Test
public void getDataTest() {
    when(dataSetDao.getDataSetList()).thenReturn(getMockDataSetList());
    when(serviceUtil.getDataFromEndpoint(anyInt(), anyList(), anyString(), any(TypeToken.class), anyString())).thenReturn(getMockDataList(Data.class));
    List<Data> dataList = noaaDataService.getData();
    verify(serviceUtil, times(11)).getDataFromEndpoint(anyInt(), anyList(), anyString(), any(TypeToken.class), anyString());
    assertEquals(11, dataList.size());
}
private <T> List<T> getMockDataList(T type) {
    List<Data> dataList = new ArrayList<>();
    for (int i = 0; i < 1; ++i) {
        dataList.add(new Data());
    }
    return (List<T>) dataList;
}

提前谢谢。

问题是您的getDataFromEndpoint(...)方法在其返回类型中是泛型的,并且其T类型参数仅通过提供

<T> T Mockito.any(Class<T> type)

当您传入类文字TypeToken.class时,它只是Class<TypeToken>,而不是所需的类型Class<TypeToken<Data>>

因此,serviceUtil.getDataFromEndpoint(...)的推断类型将是List<Object>,而不是所需的List<Data>。因此,下一步将失败,因为推断的类型返回

when(...)

将是

OngoingStubbing<List<Object>>

而不是所需的

OngoingStubbing<List<Data>>

并且只接受List<Object>,而不是List<Data>,因为List<Data>不是List<Object>的子类型。

解决方案是以以下形式为泛型serviceUtil.getDataFromEndpoint(...)提供类型见证:

serviceUtil.<Data> getDataFromEndpoint(...)

你的代码应该使用所有主要的编译器进行编译,无论是JDK,Eclipse,IntelliJ IDEA还是Netbeans。广义目标类型推理通常效果很好,但在这种情况下,您为它提供了错误的参数。

相关内容

  • 没有找到相关文章

最新更新