thenReturn 重载方法有替代方案 - 如何解决这个问题?

thenReturn overloaded method has alternatives - how can this be resolved?

我在 class 中有一个函数,例如:

def saveToken(token: Token, ttl: Instant, client: Client, partner: Partner, info: Info): Future[EitherErrorsOr[Done]]

EitherErrorsOr是:

type EitherErrorsOr[A] = scala.Either[Errors, A]

Errors是我们内部的Errorsclass

当我尝试如下模拟 saveToken 时:

when(
      mockService.saveToken(
        any(), any(), any(), any(), any()
    )
  ).thenReturn(Right(NoOpVal).toFut)

然后我得到一个错误,例如:

overloaded method value thenReturn with alternatives:
  (x: scala.concurrent.Future[EitherErrorsOr[Done]],x: scala.concurrent.Future[EitherErrorsOr[Done]]*)org.mockito.stubbing.OngoingStubbing[scala.concurrent.Future[EitherErrorsOr[Done]]] <and>
  (x: scala.concurrent.Future[EitherErrorsOr[Done]])org.mockito.stubbing.OngoingStubbing[scala.concurrent.Future[EitherErrorsOr[Done]]]
 cannot be applied to (scala.concurrent.Future[scala.util.Right[Nothing,NoOp]])
      ).thenReturn(Right(NoOpVal).toFut)

为什么 thenReturn 想出了那么多备选方案?

注意: Done 是我们内部的 class 表示操作完成, toFut 转换为 Future 对象,NoOpVal 只是为测试目的而创建的某种类型

您遇到的问题属于 return 类型。方法的return类型是Future[EitherErrorsOr[Done]],也就是Future[Either[Errors, Done]].

我们现在来分析Right(NoOpVal).toFut的类型。 Right的实现是:

final case class Right[+A, +B](b: B) extends Either[A, B] {
  def isLeft = false
  def isRight = true
}

假设 NoOpValA 类型,当调用 Right(NoOpVal) 时你得到一个 Right[Nothing, A] 类型的实例,因为你没有提供第一个泛型至 Right.

Right[Nothing, A] 无法转换为 Future[EitherErrorsOr[Done]].

你是怎么解决的?简单的做:

when(mockService.saveToken(any(), any(), any(), any(), any()))
    .thenReturn(Right[Errors, Done](NoOpVal).toFut)

并确保 NoOpVal 扩展 Done.