數據訪問的單元測試 搜索了一下“數據訪問層如何做單元測試?”,還真的有很多廣大社區網友的心得。 JAVA的數據訪問層其實可以寫單元測試,但測完之後就不會有變化。 因為數據訪問層本就不允許包含業務邏輯,寫一個測一個刪一個,留著沒有意義,正兒八經留著還會增加額外工作量。 1、編寫測試用例,包含了初始化測 ...
數據訪問的單元測試
搜索了一下“數據訪問層如何做單元測試?”,還真的有很多廣大社區網友的心得。
JAVA的數據訪問層其實可以寫單元測試,但測完之後就不會有變化。
因為數據訪問層本就不允許包含業務邏輯,寫一個測一個刪一個,留著沒有意義,正兒八經留著還會增加額外工作量。
1、編寫測試用例,包含了初始化測試環境的數據,測試目標代碼,最後清空數據。
這種方法看似很規範,其實初始化測試環境的數據時都有可能報錯,你寫的時候測試是通過了,但你無法控制其他成員不操作資料庫導致環境發生改變,一段時間後回過頭再運行單元測試不一定能通過。
2、H2記憶體資料庫單元測試。
比上面多了一步創建一段腳本建表。獨立於測試環境的記憶體資料庫,不用擔心環境被改變。
但存在資料庫腳本同步的問題,表結構調整要隨時更新腳本。
3、Hibernate工具映射生成資料庫。
比上面好一點,解決了同步問題,以領域模型為主,而不以資料庫表結構為主。
但是必須是Hibernate,還得切換配置文件數據連接字元串,沒切完蛋了。
最佳的實踐是:資料庫有變化,就測試相關的DAL,測試完就刪除/註釋用例和測試產生的數據。
因為我們的DAL里並不會包含業務邏輯,任何業務邏輯,只關心幾張表之間自己的事情,只要表結構不動,就沒必要重新測。
難點就是不包含任何業務邏輯。
舉個例子:
SELECT * FROM [TABLE] WHERE STATE=1
這段SQL語句里其實就包含了一定業務,STATE=1。
DAL其實需要明白STATE=1是什麼意思,如果化解?如下
SELECT * FROM [TABLE] WHERE STATE=:STATE
讓STATE=1是什麼意思讓上面的業務層去解釋。
業務邏輯的單元測試
要求業務邏輯層能獨立運行,不允許依賴數據訪問層。
許多人一開始就理解錯誤了,以為三層架構是WEB引用BUSINESS引用DAL,這是誤傳。
其實三層架構只是大致分為WEB / BUSINESS / DAL三層,相對於桌面應用程式兩層架構 CLIENT/SERVER 來說的。
實際操作過程中,會用到依賴反轉讓DAL依賴BUSINESS,BUSINESS只依賴數據訪問介面。
BUSINESS只能包含業務邏輯,不能去依賴其他層了,不然難以TDD DDD。
原理明白了,我們單元測試還是跑不起來,因為運行時會告訴我們數據訪問介面沒有實現。
這裡最佳的實踐是:用MOCK模擬數據訪問介面實現,定義入參和返回值,單獨測試業務邏輯。
mockito
@Mock SsoTokenRepository ssoTokenRepository; @Mock SsoSessionRepository ssoSessionRepository; @InjectMocks AuthorizedService authorizedService; @Test public void getAccessToken() throws Exception { //定義返回值 SsoToken result= new SsoToken(); result.setToken("123"); //定義入參 final String accessToken="444"; when(ssoTokenRepository.get(anyString())).thenReturn(result);//模擬一個倉儲偽類 SsoToken ssoToken = authorizedService.getAccessToken(accessToken); verify(ssoTokenRepository).get(accessToken);//驗證模擬的偽類有沒有被執行到 assertEquals(result.getToken(),ssoToken.getToken()); System.out.println(result.getToken()); }
這樣在項目的任何階段都可以重現單元測試,並且可以作為CMMI評審的測試用例。
後面是給代碼美顏: