2017-08-02 70 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

更正了我的代碼示例並刪除了一些噪音。抱歉,如果您有時間,請更新您的代碼。謝謝! –