私たちは Scala 2.10.2 を使用しており、DAO にはSlick 1.0.1 を使用しています。私たちは ScalaMock で DAO をモックしようとしています。私は、モックされた DAOを注入する良い方法を見つけようとしています。私は Java を数年間使用してきましたが、2 週間前に 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]
Users やその他のシングルトン 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()
、これにより余計な混乱が生じることはありません。ただし、 vars の使用はDAORepo
悪臭がするので、これを改善するための提案があるかどうか疑問に思っています。
Real-World Scala: Dependency Injection (DI) and 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
これは の 20 個の var を の 1 つの var に置き換えますが、varobject DAOWrapper
なしでこれを行うためのクリーンな方法があるはずです。