Scala 如何使用可配置的数据库将光滑的代码组织成单独的可测试单元?
我有几个应用程序的代码库,其中有一个共享数据库,使用Slick进行数据库访问。部分代码(如公共表映射)位于公共库中。我希望能够在这些项目上运行两种测试:Scala 如何使用可配置的数据库将光滑的代码组织成单独的可测试单元?,scala,slick,slick-3.0,Scala,Slick,Slick 3.0,我有几个应用程序的代码库,其中有一个共享数据库,使用Slick进行数据库访问。部分代码(如公共表映射)位于公共库中。我希望能够在这些项目上运行两种测试: 使用真实数据库的测试 使用内存中H2数据库的其他测试 为了支持这一点,我尝试了几种组织代码的方法,但总是在某些时候遇到困难。我最近的尝试是使用DatabaseConfig方法,将数据库定义(包括数据库、概要文件和表定义)传递给执行数据库操作的对象(让我们称之为服务)。这样,理论上,我可以通过传入我想要测试的数据库定义来轻松测试服务。实际上,
- 使用真实数据库的测试
- 使用内存中H2数据库的其他测试
DatabaseConfig
方法,将数据库定义(包括数据库、概要文件和表定义)传递给执行数据库操作的对象(让我们称之为服务)。这样,理论上,我可以通过传入我想要测试的数据库定义来轻松测试服务。实际上,我在服务之间的交互中遇到问题,因为类型不适合
我创建了一个简化的示例,展示了我遇到的问题:
import slick.basic.DatabaseConfig
import slick.jdbc.JdbcProfile
import slick.lifted.Rep
import scala.concurrent.Future
trait HasProfile {
val profile: JdbcProfile
}
trait HasId {
val id: Rep[Long]
}
trait Table_Person {
this: HasProfile =>
case class PersonRow(personId: Long, lastName: String)
import profile.api._
class Person(tableTag: Tag) extends Table[PersonRow](tableTag, "person") with HasId {
val personId = column[Long]("person_id", O.PrimaryKey, O.AutoInc)
val lastName = column[String]("last_name")
override val id = personId
val * = (personId, lastName).mapTo[PersonRow]
}
lazy val Person = TableQuery[Person]
}
class DatabaseWrapper {
private val databaseConfig: DatabaseConfig[JdbcProfile] = DatabaseConfig.forConfig("PersonDatabase")
def db = databaseConfig.db
object Schema extends HasProfile with Table_Person {
override val profile = databaseConfig.profile
}
}
class PersonService(val databaseWrapper: DatabaseWrapper) {
import databaseWrapper.Schema._
val loadService = new LoadService(databaseWrapper)
def load(id: Long): Future[Option[PersonRow]] = loadService.load[PersonRow](Person, id)
}
class LoadService(val databaseWrapper: DatabaseWrapper) {
import databaseWrapper.Schema.profile.api._
def load[R](tableQuery: TableQuery[_ <: Table[R] with HasId], id: Long): Future[Option[R]] = databaseWrapper.db.run(tableQuery.filter(_.id === id).result.headOption)
}
import slick.basic.DatabaseConfig
导入slick.jdbc.jdbc配置文件
导入slick.lifted.Rep
导入scala.concurrent.Future
特征轮廓{
val配置文件:JdbcProfile
}
特征哈西德{
val id:Rep[Long]
}
个人特质表{
这个:HasProfile=>
案例类PersonRow(personId:Long,lastName:String)
导入profile.api_
类Person(tableTag:Tag)使用HasId扩展表[PersonRow](tableTag,“Person”){
val personId=列[Long](“person_id”,O.PrimaryKey,O.AutoInc)
val lastName=列[字符串](“姓氏”)
覆盖val id=personId
val*=(personId,lastName).mapTo[PersonRow]
}
lazy val Person=TableQuery[Person]
}
类数据库包装器{
private val databaseConfig:databaseConfig[JdbcProfile]=databaseConfig.forConfig(“PersonDatabase”)
def db=databaseConfig.db
对象架构使用表“”扩展HasProfile{
覆盖val profile=databaseConfig.profile
}
}
类PersonService(val databaseWrapper:databaseWrapper){
导入databaseWrapper.Schema_
val loadService=新的loadService(databaseWrapper)
def load(id:Long):Future[Option[PersonRow]]=loadService.load[PersonRow](个人,id)
}
类LoadService(val databaseWrapper:databaseWrapper){
导入databaseWrapper.Schema.profile.api_
def load[R](tableQuery:tableQuery[\uu]也可以查看(对于“真实”持久性单元测试,不是H2)也可以查看(对于“真实”持久性单元测试,不是H2)
Error:(51, 79) type mismatch;
found : slick.lifted.TableQuery[PersonService.this.databaseWrapper.Schema.Person]
required: PersonService.this.loadService.databaseWrapper.Schema.profile.api.TableQuery[_ <: PersonService.this.loadService.databaseWrapper.Schema.profile.api.Table[PersonService.this.databaseWrapper.Schema.PersonRow] with HasId]
(which expands to) slick.lifted.TableQuery[_ <: PersonService.this.loadService.databaseWrapper.Schema.profile.Table[PersonService.this.databaseWrapper.Schema.PersonRow] with HasId]
def load(id: Long): Future[Option[PersonRow]] = loadService.load[PersonRow](Person, id)