2017-02-23 67 views
2

我該如何測試一個返回布爾值的方法,並且像這樣實現?單元測試JPA查詢

return entityManager.createQuery("SELECT(i) FROM Items i WHERE o.id=:id", Long.class).setParameter("id", id).getSingleResult() == 1; 

entityManager被注入課堂。

我想我大概應該驗證createQuery被調用此查詢,然後setParameter被調用id,然後進行比較,然而結果是,沒有這樣的測試一個簡單的代碼行像有點大材小用這個? 我特別覺得在單元測試中使用整個select語句會感到不舒服。這似乎更像是我的實現細節。但是,還有什麼其他方式來檢查查詢是否實際檢查了COUNT項並執行其他操作?

回答

2

我猜你有這種方法作爲某種存儲庫類的一部分。

我會建議讓版本庫層離開單元測試套件。 一般而言,您不應該在存儲庫方法中使用任何邏輯(如果有的話,這些邏輯是微不足道的),或者您至少應該爲此努力。

從我個人的經驗來看,你最終應該在單元測試的基礎上加入一些集成測試套件,並且在集成測試中總是首先在我的列表中存儲庫方法,並且是其餘IT部門的基礎試驗。

我能想到的唯一例外是當您使用Criteria API有條件地構建您的查詢時。但是,再次強調集成測試也是適當的。

那是我的意見,但呼叫是你到底..

+0

用一般的經驗法則來增加這個(正確的)答案:用集成測試測試應用程序邊界處的代碼(在這種情況下是應用程序 - DB);在單元測試中測試只依賴於你的應用的其他「部分」的代碼 – crizzis

2

在Java程序單元測試SQL語句是比較困難的,因爲你正在穿越「單位」的邊界。單元的傳統定義是它是一個單獨的被測試的類。然而,這並不是非常有用,因爲它是一種全有或全無的分類,它會在測試覆蓋率上造成巨大的差距,因爲沒有任何好處。最好是擴展單元測試工具,以支持必須可靠地協同工作的組合單元。

一種方法是創建一個模擬,檢查傳遞的參數並傳遞適當的返回值。但是,這並不檢查邏輯或計算。這可能是必要的第一步。

另一種方法是使用內存數據庫,該數據庫能夠理解您正在使用的SQL類型,並且可以在每次測試或會話開始時填充所需的數據。這將比嘲笑返回值更深入地測試您的設計和代碼。它驗證你的語法和你的語義,同時速度非常快,是單元測試最有用的屬性之一。