Java 泛型:<?> vs capture<?>



我试图嘲笑ScheduledExecutorService,我在泛型方面遇到了问题。

下面是一个片段:

ScheduledFuture<?> future = mock(ScheduledFuture.class);
ScheduledExecutorService scheduledExecutorService = 
Mockito.mock(ScheduledExecutorService.class);
when(scheduledExecutorService.schedule(Mockito.any(Runnable.class), anyLong(), any(TimeUnit.class))).thenReturn(future);

这不会编译并显示以下错误:

Error:(20, 109) java: no suitable method found for 
  thenReturn(java.util.concurrent.ScheduledFuture<capture#1 of ?>)
method org.mockito.stubbing.OngoingStubbing.thenReturn(java.util.concurrent.ScheduledFuture<capture#2 of ?>) is not applicable
  (argument mismatch; java.util.concurrent.ScheduledFuture<capture#1 of ?> cannot be converted to java.util.concurrent.ScheduledFuture<capture#2 of ?>)
method org.mockito.stubbing.OngoingStubbing.thenReturn(java.util.concurrent.ScheduledFuture<capture#2 of ?>,java.util.concurrent.ScheduledFuture<capture#2 of ?>...) is not applicable
  (argument mismatch; java.util.concurrent.ScheduledFuture<capture#1 of ?> cannot be converted to java.util.concurrent.ScheduledFuture<capture#2 of ?>)

如果我声明ScheduledFuture没有泛型,它会编译并带有警告。

 ScheduledFuture future 

有什么办法可以正确吗?我的意思是,我可以使用任何通配符,以便在没有警告的情况下进行编译?

以下方法在类型上正确工作:

<T> ScheduledFuture<?> thenReturnMockFuture(
    OngoingStubbing<ScheduledFuture<T>> stubbing) {
  // Declare a local abstract class, so that future is type-correct.
  abstract class ScheduledFutureT implements ScheduledFuture<T> {}
  ScheduledFuture<T> future = mock(ScheduledFutureT.class);
  stubbing.thenReturn(future);
  return future;
}

然后像这样打电话:

ScheduledExecutorService scheduledExecutorService = 
    mock(ScheduledExecutorService.class);
ScheduledFuture<?> future = 
    thenReturnMockFuture(
        when(scheduledExecutorService.schedule(...)));

我认为你也可以这样做(没有方法,但使用抽象的本地类):

ScheduledFuture<?> future = mock(ScheduledFutureT.class);
doReturn(future).when(scheduledExecutorService).schedule(...);

请注意doReturn不是类型安全的警告,因此您必须确保调用的方法是返回ScheduledFuture<?>

ScheduledFuture中绑定的通配符会导致类型推断出现问题。您需要future声明为 ScheduledFuture<?> 吗?

如果没有,则以下内容将起作用:

ScheduledFuture future = Mockito.mock(ScheduledFuture.class);
ScheduledExecutorService scheduledExecutorService =
        Mockito.mock(ScheduledExecutorService.class);
Mockito.when(scheduledExecutorService.schedule(Mockito.any(Runnable.class), Mockito.anyLong(), Mockito.any(TimeUnit.class))).thenReturn(future);

如果确实需要将future声明为 ScheduledFuture<?>则以下内容将起作用,因为doReturn()不是类型安全的:

ScheduledFuture<?> future = Mockito.mock(ScheduledFuture.class);
ScheduledExecutorService scheduledExecutorService =
        Mockito.mock(ScheduledExecutorService.class);
Mockito.doReturn(future).when(scheduledExecutorService).schedule(Mockito.any(Runnable.class), Mockito.anyLong(), Mockito.any(TimeUnit.class));

相关内容

  • 没有找到相关文章

最新更新