【发布时间】:2017-01-31 09:46:28
【问题描述】:
我正在使用围绕 Slick 2.1.0 的包装类(我知道)处理现有代码库。这个包装器有一个名为transaction 的通用方法——它需要一个(f: => T)(所以它是按名称传递的)。我需要模拟这个类进行单元测试。我们还在使用 Mockito 1.10.19(我知道),它不会让我模拟一个传名(我相信...)。所以我坚持实现这个包装类所依赖的底层特征。
直接的问题是:我想模拟这个transaction 方法,所以它什么都不做。我正在测试的代码通过(f: => Unit)。所以我想实现这个方法来返回一个Future.Done。 (我有没有提到我们使用的是 Finagle 而不是 Scala 期货?)但是这种方法是通用的。我如何正确专业化?
这是我目前的尝试:
val mockDBM = new DatabaseManager {
override def transaction[@specialized(Unit) T](f: => T): Future[T] = Future.value(f)
def transaction(f: => Unit): Future[Unit] = Future.Done
}
当然,我在编译时收到have same type after erasure 错误。显然我不知道@specialized 是如何工作的。
我该怎么办?也许我毕竟可以使用 Mockito?或者我需要了解专门化泛型方法的实际含义?
我找到了这个,它可能包含了答案,但是我没有正式的 FP 背景,我根本不了解这个:How can one provide manually specialized implementations with Scala specialization?
【问题讨论】:
-
为什么需要专业化?覆盖
DatabaseManager上的transcation方法还不足以实现您想要的吗? -
我不得不再试一次,因为我在质疑我的理智。特征本身定义了泛型方法。我需要用我自己的泛型覆盖它。但是,如果泛型用于
Unit类型,我只能返回Future.Done。因此专业化。我确定我错过了一些东西。这是什么? -
所以你想要
Future.Done而不是Future.value(Unit)? -
DatabaseManager是我注入到被测类的依赖项。我无法控制传入的f。我想要完全忽略f,无论如何都返回Future.Done。如果我运行实际传入的f,它将引发异常,因为在被测类中,f依赖于 Slick 提供的隐式,而我的模拟类没有。我需要找到一种方法来破解这个问题,这样f就不会被实际执行。