我們使用的是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示例非常有幫助 –