【问题标题】:best way to test Slick session/transaction code测试 Slick 会话/事务代码的最佳方法
【发布时间】:2014-10-31 15:16:28
【问题描述】:

用于创建datasource 我有

object MyDataSource {
 priavte lazy val dataSource: javax.sql.DataSource = {
 val ds = new BasicDataSource
 val conf = ConfigFactory.load()

 val url = conf.getString("jdbc-url")
 val driver = conf.getString("jdbc-driver")
 val username = conf.getString("db-username")
 val password = conf.getString("db-password")
 val port = conf.getString("db-port")

 val maxActive = conf.getInt("max-active")

 val maxIdle = conf.getInt("max-idle")
 val initSize = conf.getInt("init-size")

 ds.setDriverClassName(driver)
 ds.setUsername(username)
 ds.setPassword(password)
 ds.setMaxActive(maxActive)
 ds.setMaxIdle(maxIdle)
 ds.setInitialSize(initSize)

 ds.setUrl(url)
 ds
 } 

lazy val database = Database.forDataSource(dataSource)
}

MyDataSource 使用如下

def insertCompany = {    
   MyDataSource.database.withSession{ implicit session =>
   company.insert(companyRow)

   }
}

现在进行测试,我有 trait DatabaseSpec 加载测试数据库(指向测试数据库)配置并具有以下夹具

def withSession(testCode: Session => Any) {
val session = postgres.createSession()
session.conn.setAutoCommit(false)
try {
  testCode(session)
} finally {
  session.rollback()
  session.close()
}

}

然后测试代码可以混入DatabaseSpec并使用withSession来测试事务代码。

现在的问题是,在 insertCompany 中将 MyDataSource.database.withSessionDataSource 抽象出来以便可以使用 DatabaseSpec 测试方法并指向测试数据库的最佳做法是什么?

【问题讨论】:

标签: scala slick scalatest


【解决方案1】:

能够交换一个值的最佳方式,例如用于 prod 和 testing 是在该值中参数化您的代码。例如

def insertCompany(db: Database) = db.withSession(company.insert(companyRow)(_))

class DAO(db:Database){
    def insertCompany = db.withSession(company.insert(companyRow)(_))
}

保持简单。避免不必要的复杂性,例如 Cake 模式、DI 框架或 mixin 组合。

如果您需要传递多个值...将它们聚合到“配置”类中。如果您想避免随着东西的积累而编写一个巨大的配置类,请组合多个具有不同目的的配置类以针对不同的事物。

如果您发现自己将配置对象传递给所有函数,则可以将它们标记为隐式,这至少可以节省调用站点代码的开销。或者,您可以使用 scalaz 的 monadic 函数组合之类的东西来避免调用站点和定义站点代码开销来传递配置。它有时被称为 Reader monad,但它只是一种支持理解的 1 参数函数组合。

Slick 2.2 将提供类似的开箱即用功能,让您想要的东西变得非常简单。

另外,这是我目前正在使用的一种方法,一种可组合的配置对象“TMap”。此代码示例逐步展示了如何从全局导入中获取参数化函数,并使它们隐含使用 TMap 并删除大多数样板:https://github.com/cvogt/slick-action/blob/0.1/src/test/scala/org/cvogt/di/TMapTest.scala#L49

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-17
    • 2010-12-05
    • 2010-09-28
    • 2018-08-12
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-16
    相关资源
    最近更新 更多