我正在处理一个用例,我的应用程序需要一个特性对象Table
。我有一个将在开发环境中使用的实现TableImpl()
。但是,我希望能够在测试环境中将TableImpl()
与MockTableImpl()
切换。
最常用的scala方法是什么?
我可以使用工厂来提供TableImpl()
的单身人士,但工厂如何决定退回TableImpl()
或MockTableImpl()
?
答案 0 :(得分:1)
我建议反对让询问组件的依赖关系。相反,让组件的创建者给它它的依赖关系(依赖注入或控制反转)。这种方法可以更好地适应惯用语。
只是将依赖项作为构造函数参数传递。这样,就无法构建没有有效依赖关系的类:
class MyApp (table: Table) {
...
}
class TableImpl() extends Table // singleton
// in production
new MyApp (table = new TableImpl()) // or you can use factory or whatever
// in test (assuming scalatest and scalamock)
new MyApp (table = mock[Table])
答案 1 :(得分:1)
trait Table {
def size: Int
}
object TableImpl extends Table { //SINGLETON
def size = Math.abs(-5)*11 //real logic
}
某些应用程序类(它可能扩展App
特征)。
class AppContext(table: Table) {
def run = ()
}
使用单例引用实例化应用程序。
new AppContext(TableImpl).run
或者为测试原因构建应用程序上下文。
val mock = mock[Table]
//set mock stuff
new AppContext(mock).run
建议您使用Macwire,Guice或Cake模式等DI
object
。我的建议是始终将依赖关系显式化 - 不要直接在类体中使用单个foo.A
名称,而是将其注入。