首页 > 解决方案 > thenReturn 重载方法有替代方法 - 如何解决?

问题描述

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

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

并且EitherErrorsOr是:

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

Errors是我们的内部Errors

当我尝试saveToken如下模拟时:

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

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

overloaded method value thenReturn with alternatives:
  (x$1: scala.concurrent.Future[EitherErrorsOr[Done]],x$2: scala.concurrent.Future[EitherErrorsOr[Done]]*)org.mockito.stubbing.OngoingStubbing[scala.concurrent.Future[EitherErrorsOr[Done]]] <and>
  (x$1: 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是我们的内部类,表示操作完成, toFut转换为Future对象,NoOpVal只是为了测试目的而创建的某种类型

标签: scalaunit-testingmockitoscalatest

解决方案


您遇到的问题在于返回类型。该方法的返回类型是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
}

让我们假设它NoOpVal是 type A,当调用时Right(NoOpVal)你会得到一个 type 的实例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


推荐阅读