整合測試
在無需部署到應用伺服器或連線到其他企業基礎設施的情況下,進行整合測試非常重要。這樣做可以讓你測試以下方面,例如:
-
Spring IoC 容器上下文的正確連線(wiring)。
-
使用 JDBC 或 ORM 工具進行資料訪問。這可以包括 SQL 語句的正確性、Hibernate 查詢、JPA 實體對映等。
Spring Framework 在 spring-test
模組中提供了對整合測試的一流支援。實際的 JAR 檔名可能包含版本號,也可能採用完整的 org.springframework.test
形式,這取決於你從哪裡獲取(有關說明,請參見依賴管理章節)。此庫包含 org.springframework.test
包,其中包含用於與 Spring 容器進行整合測試的有價值的類。這種測試不依賴於應用伺服器或其他部署環境。此類測試的執行速度比單元測試慢,但比依賴於部署到應用伺服器的等效 Selenium 測試或遠端測試快得多。
單元測試和整合測試支援以註解驅動的 Spring TestContext Framework 的形式提供。TestContext Framework 不依賴於實際使用的測試框架,這允許在各種環境(包括 JUnit、TestNG 等)中對測試進行檢測。
以下部分概述了 Spring 整合支援的高階目標,本章的其餘部分將重點介紹專門主題:
整合測試的目標
Spring 的整合測試支援具有以下主要目標:
-
管理測試之間的 Spring IoC 容器快取。
-
提供測試夾具例項的依賴注入。
-
提供適合整合測試的事務管理。
-
提供幫助開發者編寫整合測試的Spring 特定基類。
接下來的幾個部分將描述每個目標,並提供實現和配置細節的連結。
上下文管理和快取
Spring TestContext Framework 提供 Spring ApplicationContext
例項和 WebApplicationContext
例項的一致載入以及這些上下文的快取。對載入的上下文進行快取的支援非常重要,因為啟動時間可能成為一個問題——並非由於 Spring 本身的開銷,而是由於 Spring 容器例項化的物件需要時間進行例項化。例如,一個包含 50 到 100 個 Hibernate 對映檔案的專案可能需要 10 到 20 秒來載入對映檔案,在每個測試夾具中執行每個測試之前都產生此成本會導致整體測試執行變慢,從而降低開發者的生產力。
測試類通常宣告用於 XML 或 Groovy 配置元資料的資源位置陣列(通常在類路徑中),或者用於配置應用程式的元件類陣列。這些位置或類與生產部署中 web.xml
或其他配置檔案中指定的相同或相似。
預設情況下,一旦載入,配置好的 ApplicationContext
會在每個測試中被複用。因此,設定成本只在每個測試套件中發生一次,隨後的測試執行會快得多。在此上下文中,“測試套件”一詞指在同一個 JVM 中執行的所有測試——例如,給定專案或模組透過 Ant、Maven 或 Gradle 構建執行的所有測試。萬一測試破壞了應用程式上下文並需要重新載入(例如,透過修改 Bean 定義或應用程式物件的狀態),TestContext Framework 可以配置為在執行下一個測試之前重新載入配置並重建應用程式上下文。
測試夾具的依賴注入
當 TestContext Framework 載入你的應用程式上下文時,它可以選擇性地使用依賴注入來配置測試類的例項。這提供了一種方便的機制,透過使用應用程式上下文中的預配置 Bean 來設定測試夾具。這裡的一個顯著優勢是,你可以在各種測試場景中複用應用程式上下文(例如,用於配置 Spring 管理的物件圖、事務代理、DataSource
例項等),從而避免為每個單獨的測試用例重複複雜的測試夾具設定。
舉個例子,考慮這樣一個場景:我們有一個類 (HibernateTitleRepository
) 實現了 Title
領域實體的資料訪問邏輯。我們希望編寫整合測試來測試以下方面:
-
Spring 配置:基本上,所有與
HibernateTitleRepository
Bean 配置相關的內容是否正確且存在? -
Hibernate 對映檔案配置:是否所有內容都正確對映,並且延遲載入設定是否正確?
-
HibernateTitleRepository
的邏輯:這個類的配置例項是否按預期工作?
請參見 TestContext Framework 中的測試夾具依賴注入。
事務管理
訪問真實資料庫的測試中的一個常見問題是它們對持久化儲存狀態的影響。即使你使用開發資料庫,狀態的改變也可能影響未來的測試。此外,許多操作——例如插入或修改持久化資料——不能在事務外部執行(或驗證)。
TestContext Framework 解決了這個問題。預設情況下,該框架為每個測試建立一個事務並回滾。你可以編寫程式碼,假設事務的存在。如果在測試中呼叫經事務代理的物件,它們會根據其配置的事務語義正確執行。此外,如果測試方法在為該測試管理的事務中執行時刪除了選定表的內容,事務會預設回滾,資料庫會恢復到執行測試之前的狀態。透過使用測試的應用程式上下文中定義的 PlatformTransactionManager
Bean,為測試提供事務支援。
如果你希望事務提交(這不常見,但在你希望特定測試填充或修改資料庫時偶爾有用),你可以透過使用 @Commit
註解來告訴 TestContext Framework 提交事務而不是回滾。
請參見 TestContext Framework 中的事務管理。
整合測試的支援類
Spring TestContext Framework 提供了一些 abstract
支援類,簡化了整合測試的編寫。這些基礎測試類提供了與測試框架的良好定義的連線點以及方便的例項變數和方法,使你可以訪問:
-
ApplicationContext
,用於執行顯式 Bean 查詢或測試整個上下文的狀態。 -
JdbcTemplate
,用於執行 SQL 語句查詢資料庫。你可以使用此類查詢在資料庫相關應用程式碼執行前後確認資料庫狀態,並且 Spring 確保此類查詢與應用程式碼執行在同一事務範圍內。與 ORM 工具結合使用時,請務必避免假陽性。
此外,你可能希望建立自己的自定義、應用程式範圍的超類,其中包含特定於你專案的例項變數和方法。
請參見 TestContext Framework 的支援類。