有人问过一些与这个问题有关的问题,但似乎不太合适。
我正在使用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 }