【问题标题】:How to Provide Specialized Implementations of Generic Methods in Scala?如何在 Scala 中提供泛型方法的专门实现?
【发布时间】: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 就不会被实际执行。

标签: scala generics mockito


【解决方案1】:

@specialized 不允许您提供专业化,它只是生成自己的。链接问题中提供的答案需要更改签名。从问题来看,您似乎无法更改它,在这种情况下,您很不走运。如果可以...您可能仍然不走运,具体取决于将如何调用此代码。

OTOH,“我想忽略f,但如果泛型用于Unit 类型,则只能返回Future.Done”的解决方案要简单得多:

class Default[A] {
  var x: A = _
}
object Default {
  def apply[A]() = (new Default[A]).x
}

val mockDBM = new DatabaseManager {
  override def transaction[T](f: => T): Future[T] = {
    Future.value(Default(x))
  }
}

假设你需要一个成功的未来,但不关心价值,那就是;如果您只需要任何未来,override def transaction[T](f: => T): Future[T] = Future.???

【讨论】:

  • 天啊。我很快就会到办公室并会尝试这个,但是下划线在这里解决了什么问题?
  • 没有骰子。运行 Scala 2.11.7。我得到local variables must be initialized。使用val 而不是var 我得到unbound placeholder parameter。 :(
  • 我的团队决定放弃这一点,手动进行烟雾测试。我明天某个时候会试试这个。立即投票并接受!
猜你喜欢
  • 2016-08-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多