假设我有以下特征和类:
case class Result[A](
header: String,
data: A
)
trait WebClient {
def doSomething[A : TypeTag](name: String): Future[Result[A]]
}
在本例中,doSomething
是有问题的polymorphic method。如何创建一个实现WebClient
并具有最小行为的MockWebClient
?(最小的行为就是什么都不做。)最好,我不想返回Future.failed
,因为从语义上讲,结果不应该表示失败。此外,我不想将Result[A]
的A
类型更改为covariant or contravariant (即+A
或-A
),因为它在上下文中没有太多意义。
这是我最好的尝试(仍然不能编译)。它使用一个带有泛型工厂的泛型类来模拟doSomething
方法的返回值。但是,我找不到A
和B
之间的正确关系
class MockWebClient[A](val factory: () => Result[A]) extends WebClient {
override def doSomething[B >: A : TypeTag](name: String): Future[Result[B]] = {
Future.successful(factory())
}
}
另外,我使用过mockito-scala
,但由于类型擦除的原因,它不能工作。scalamock
似乎也很有趣,但我想知道是否有一种方法可以让类似于我的解决方案的东西工作。
发布于 2020-06-29 20:57:00
如果您确定测试中不会使用data
字段,则可以使用null.asInstanceOf[A]
欺骗编译器
val mockWebClient = new WebClient {
override def doSomething[A](name: String): Future[Result[A]] =
Future.successful(Result(name, null.asInstanceOf[A]))
}
如果A
形成一个Monoid
,你可以用一种类型安全的方式来实现,比如
import cats.Monoid
import cats.implicits._
trait WebClient {
def doSomething[A: Monoid](name: String): Future[Result[A]]
}
val mockWebClient = new WebClient {
override def doSomething[A: Monoid](name: String): Future[Result[A]] =
Future.successful(Result(name, implicitly[Monoid[A]].empty))
}
mockWebClient.doSomething[String]("woohoo")
https://stackoverflow.com/questions/62638170
复制相似问题