有人问过一些与这个问题有关的问题,但似乎不太合适。

我正在使用Cake模式在生产代码中插入“存储”系统,并在测试中插入存根存储系统。一切都很棒,但是原始类中有一个正在实例化的类,也需要将该存根存储系统混入其中。由于它隐藏在实现中,因此我无权访问它。

事情看起来像这样:

class Main { this: Storage =>
  ...
  val used = Used(...)
  ...
}

class Used { this: Storage =>
  ...
}

当测试“Used”时,我只是new Used with StubStorage然后关闭。我曾经对Main做同样的事情,但是那是在它​​使用Used之前。现在,Main使Used的天真实例化,我遇到了这个问题。

我想这样尝试:
class Main[T <: Storage] { this: T =>
  ...
  val used = Used[T](...)
  ...
}

class Used[T <: Storage] { this: T =>
  ...
}
object Used {
  def apply[T <: Storage](...) = new Used(...) with T
}

但是当然这是行不通的,因为编译器没有足够的信息来发现T。为此有魔术吗?我已经玩了一段时间,似乎很麻烦,标准OO注入(inject)方法实际上没有那么麻烦,但是我可能会遗漏一些东西。

我已经研究了隐式的Factory概念,但是我无法将其变成可用于mixin的形状。

编辑:公开编写问题的清晰度令人惊讶。 :)我没有按照我最初的意图解决问题,但是对于实际问题有一个简单的解决方案:
trait UsedProvider {
  def createUsed = Used.apply _
}

class Main { this: Storage with UsedProvider =>
  val used = createUsed(...)
}

然后,我将在测试中执行以下操作:new Main with StubStorage with StubUsedProvider

最佳答案

我也没有解决您的原始问题,但是您是否考虑过使用Main的抽象类,并在需要的地方提供used的值?

abstract class Main { this: Storage =>
  val s = "s"
  val used: Used
}

然后像这样实例化:
val main = new Main with StubStorage { val used = new Used(s) with StubStorage }

09-25 17:41
查看更多