我如何用许多护腕模拟方法?

问题描述

我有方法

get[T](method: String,additionalHeaders: (String,String)*)(block: HttpResponse => Try[T]): Future[T]

我是这样尝试的:

var serviceClient = mock[ServiceClient]
    (serviceClient .get _).expects(*,*)

但得到错误

org.scalamock.function.MockFunction3 cannot be cast to org.scalamock.function.MockFunction2
java.lang.classCastException: org.scalamock.function.MockFunction3 cannot be cast to org.scalamock.function.MockFunction2
    at .TestSpec.$anonfun$new$1(TestSpec.scala:22)

不管参数如何,我只想返回同一个对象

解决方法

在您的情况下,您使用了带有三个参数的咖喱函数:

def get[T](method: String,additionalHeaders: (String,String)*)
  (block: HttpResponse => Try[T]): Future[T] = ???

和调用 get 可以表示为:

Function3[String,Seq[(String,String)],HttpResponse => Try[T],Future[T]]

如果我们不咖喱get

trait ServiceWithUncurriedGet {
  def uncurriedGet[T]: (String,HttpResponse => Try[T]) => Future[T] =
    new Function3[String,Future[T]] {
      override def apply(v1: String,v2: Seq[(String,v3: HttpResponse => Try[T]): Future[T] =
        serviceClient.get(v1,v2: _*)(v3)
    }
}

并且我们可以使用此服务将 uncurriedGet 模拟为具有 3 个参数的函数:

val serviceWithUncurriedGetClient = mock[ServiceWithUncurriedGet]
serviceWithUncurriedGetClient.uncurriedGet[String].expects(*,*,*)

要使您的代码正常工作,您需要将 Curried 函数转换为 UnCurried 并传递类型(我使用 String 而不是 T类型参数以简化):

(
  (x: String,y: Seq[(String,f: HttpResponse => Try[String]) => 
    serviceClient.get(x,y: _*)(f)
).expects(*,*)

还需要扩展参数类型以提供编译器更多信息,并且可以将其转换为 3 个参数的函数。