我们使用的是Scala 2.10.2,我们的DAO使用的是Slick 1.0.1。我们试图用ScalaMock来嘲笑DAO,并且我试图找出注入模拟DAO的好方法。我已经使用Java好几年了,但是我刚刚在两周前开始使用Scala。我该如何在Scala中注入一个模拟的单例对象?
现在我们的代码看起来像(忽略任何语法错误,我已经凝聚了代码,而确保它仍然满足类型系统)
abstract class RichTable[T](name: String)
extends slick.driver.MySQLDriver.simple.Table[T](name) {
type ItemType = T
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
...
}
object Users extends RichTable[User]("users") {
def crypted_password = column[String]("crypted_password")
...
}
case class User(id: Option[Int] = None, crypted_password: String) {
def updatePassword(...) = {
Users.where(_.id === id).map{e => e.crypted_password}.update("asdf")
}
}
所有的DAO都来自RichTable[T]
继承单一对象
我们希望能够模拟用户和其他单例DAO对象 - 现在我们所有的单元测试都打到了数据库。但是,我们遇到的问题是如何注入模拟单例对象。我们已经想出了到目前为止的解决方案是:
object DAORepo {
var usersDAO : Users.type = Users
var anotherDAO : Another.type = Another
...
}
object Users extends RichTable[User]("users") {
def apply() : Users.type = DAORepos.usersDAO
}
def updatePassword(...) = {
Users().where(_.id === id).map{e => e.crypted_password}.update("asdf")
}
def test = {
val mockUsers = mock[Users]
DAORepo.usersDAO = mockUsers
// run test using mock repo
}
我们都在我们的参考的改变从Users
到Users()
,不加杂波过量。然而,在DAORepo
中使用变种臭味很差,我想知道是否有人有建议来改善这一点。
我读过Real-World Scala: Dependency Injection (DI)和Component Based Dependency Injection in Scala - 我想我知道如何使用特性来组成DAORepo,像
trait UsersRepo {
val usersDAO : Users.type = Users
}
trait DAORepo extends UsersRepo with AnotherRepo { }
trait UsersTestRepo {
val usersDAO : Users.type = mock[Users]
}
,但我还是不明白,我怎么会注入新的特质。我可以做类似
class DAORepoImpl extends DAORepo { }
object DAOWrapper {
var repo : DAORepo = new DAORepoImpl
}
def test = {
DAOWrapper.repo = new DAORepoImpl with UsersTestRepo
}
它取代object DAORepo
二十几瓦尔在object DAOWrapper
一个变种,但它好像有应该是一个干净的方式来做到这一点没有任何增值经销商。
感谢赏金和好运与蛋糕的图案:)它并不难,但有关于这个问题缺乏良好的资源,它解释前的Java用户 –
Sebastien Lorber谢谢,您的Spring示例非常有帮助 –