2017-08-02 35 views
8

为了访问对象,创建了一个包含函数的Slick DAO,该函数返回存储类型的动作和对象。例如:当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()

测试这两个函数和最小化代码冗余的可靠方法是什么?

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

回答

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;只是测试它的物化结果。

+0

更正了我的代码示例并删除了一些噪音。抱歉,如果您有时间,请更新您的代码。谢谢! –