【问题标题】:Reduce testing overhead when DAO contains action当 DAO 包含操作时减少测试开销
【发布时间】:2017-08-02 14:14:12
【问题描述】:

为了访问对象,创建了一个 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() 中。

什么是测试这两个功能并最大限度地减少代码冗余的可靠方法?

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

【问题讨论】:

    标签: scala slick slick-3.0


    【解决方案1】:

    注意非基于动作的函数如何将另一个函数包装在 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;只测试它的具体化结果。

    【讨论】:

    • 更正了我的代码示例并消除了一些噪音。很抱歉给您带来不便,如果您有时间,请相应地更新您的代码。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 2017-12-11
    • 2021-01-22
    • 2016-05-10
    • 2023-03-08
    相关资源
    最近更新 更多