当DAO包含操作

时间:2017-08-02 14:14:12

标签: scala slick slick-3.0

为了访问对象,创建了包含返回操作的函数和存储类型的对象的Slick DAO。例如:

def findByKeysAction(a: String, b: String, c: String = {
  Users.filter(x => x.a === a && x.b === b && x.c === c).result
}

def findByKeys(a: String, b: String, c: String): Future[Option[foo]] = {
  db.run(findByKeysAction(consumerId, contextId, userId)).map(_.headOption)
}

注意基于非动作的函数如何在db.run()中包装另一个函数。

测试这两种功能和最小化代码冗余的可行方法是什么?

我天真的方法当然可以用它们各自的测试设置来测试它们(上面是一个简单的例子;可能需要很多测试设置来满足数据库限制)。

1 个答案:

答案 0 :(得分:5)

  

注意非基于动作的函数如何在db.run()中包装另一个函数。

不是真的。您的findByKeys方法未调用findByUserIdAction,因此我正在调整此答案中的小细节。

def findByUserIdAction(userId: String) = {
  Users.filter(_.userId === userId).result
}

上面的代码返回DBIOAction。正如documentation所述:

  

就像查询一样,I / O操作只是操作的描述。创建或编写动作不会在数据库上执行任何操作。

就Slick的用户而言,DBIOAction没有有意义的测试,因为它本身没有做任何事情;它只是一个人想要做的食谱。要执行上述DBIOAction,您必须materialize,具体如下:

def findByUserId(userId: String): Future[Option[User]] = {
  db.run(findByUserIdAction(userId)).map(_.headOption)
}

具体化结果是您要测试的结果。一种方法是使用ScalaTest的ScalaFutures特性。例如,在混合了该特征的规范中,您可以使用以下内容:

"Users" should "return a single user by id" in {
  findByUserId("id3").futureValue shouldBe Option(User("id3", ...))
}

有关更多示例,请查看此Slick 3.2.0 test project:具体而言,TestSpecQueryCoffeesTest

总之,不要试图单独测试DBIOAction;只是测试其物化结果。