1. 程式人生 > >《Spring官方文件》第三部分 測試9-10章節

《Spring官方文件》第三部分 測試9-10章節

原文連結 譯者:reed7

作為 Spring 的開發團隊,我們鼓勵在開發活動中引入測試驅動開發(TDD,Test-Driveng-Development)的行為,因此本文件接下來將涵蓋 Spring 框架對整合測試的支援(以及 Spring 下單元測試的最佳實踐)。

Spring 開發團隊發現對控制反轉(IoC)的正確運用可以使針對程式碼編寫單元測試與整合測試變得更為容易(setter方法的存在,以及類裡面恰當的構造器,使得測試程式碼在無需類似服務工廠等輔助工具的前提下,也能夠方便地對各個類進行呼叫)。我們希望通過整整一章對 Spring 框架下測試相關主題的講解,讓讀者也能對我們的以上發現表示贊同。

9. Spring 框架下的測試

測試乃企業級軟體開發的重要組成部分之一。本章專注於講解採用 IoC 原則進行編碼而給單元測試帶來的好處,以及 Spring 框架對整合測試的支援如何為測試帶來幫助。(對企業開發中如何進行程式碼測試的詳盡討論不在本文件範圍之內)

10. 單元測試

比起傳統的 Java EE 開發方式,依賴注入可以弱化你的程式碼對容器的依賴。在基於 Junit 或 TestNG 的測試程式碼中,無需依賴於 Spring 或其他容器,你只需通過 new 操作符,便可以創建出組成你的應用程式的各種 POJO 物件。而通過 mock 物件(以及其它各種測試技術的綜合運用),你可以將被測試的程式碼單獨隔離開來進行測試。如果你在進行架構設計時遵循了 Spring 所推薦的模式,那麼由此帶來的諸如清晰的分層、元件化等等優點也會使你更容易地對你的程式碼進行單元測試。例如,通過 mock DAO 層或 Repositry 介面的實現,針對服務層物件的單元測試程式碼並不需要真正地訪問持久層的資料。

真正的單元測試程式碼執行的非常快,因為並不需要一整套的執行時架構去支援測試的運轉。所以在開發中強調真正的單元測試必須成為編碼方法論中的一部分將會極大地提高你的生產力。

也許沒有這一節內容的幫助你也能寫出高效的針對 IoC 應用的單元測試,但是以下將要提到的 Spring 所提供的 mock 物件和測試支援類,在一些特定的場景中會對單元測試很有幫助。

10.1 Mock 物件

10.1.1 環境

org.springframework.mock.env 包含了對抽象 Environment 和 PropertySource 的 Mock 實現(參考 3.13.1 Bean的定義檔案 和 3.13.3 PropertySource抽象)。MockEnvironment 和 MockPropertySource 對於編寫針對依賴於環境相關屬性的程式碼的,與容器無關的測試用例很有幫助。

10.1.2 JNDI

org.springframework.mock.jndi 包含了 JNDI SPI 的實現。這一實現可以讓你為你的測試套件或獨立應用配置起一個簡單的 JNDI 環境。例如,如果測試程式碼和 Java EE 容器的 JDBC 資料來源都繫結到同一個 JNDI 名字上,你就可以在測試中直接複用應用程式的程式碼和配置而不需做任何改動。

10.1.3 Servlet API

org.springframework.mock.web 包含了十分全面的 Servlet API mock 物件。這些物件在測試web 上下文,Controller 和 Filter 的時候很有用。由於這些 mock 物件是有針對性地為了與 Spring 的 Web MVC 框架共同使用而編寫的,因此相比起諸如 EasyMock 這種動態mock 物件或 MockObjects 這種替代性的 Servlet API mock 物件,使用起來要更為方便。

假如是要把 Spring MVC 和 REST 控制器與 WebApplicationContext 配置結合起來進行一番徹底的整合測試,請使用 Spring MVC 測試框架 。

10.2 單元測試支援類

10.2.1 通用支援工具

org.springframework.test.util 包含了一些供單元測試和整合測試中使用的通用工具。

ReflectionTestUtils 是一組基於反射的方法集合。在測試包含如下一些測試用例的應用時,開發人員可以使用這些工具方法應對諸如更改一個常量的值,賦值一個非公有欄位,呼叫一個非公有setter方法,或呼叫一個非公有的 配置 或 生命週期 回撥方法等測試場景:

諸如 JPA 和 Hibernate 等廣泛採用private或protected訪問方式而非公有setter方法來訪問domain entity屬性的ORM(Object-Relational Mapping)框架
@Autowired,@Inject和@Resource等用於對private或protected欄位,setter 方法和配置方法進行依賴注入的 Spring 註解。
@PostConstruct和@PreDestroy等用在生命週期回撥方法上的註解。
AopTestUtils是一組 AOP 相關工具方法的集合。這些方法可以用於幫助獲取隱藏於一重或多重 Spring 代理背後目標物件的引用。舉個栗子,你使用 EasyMock 或 Mockito mock 了一個被包裝在 Spring 代理之中的 bean,這時你可能需要對這個 mock 進行直接的訪問,從而能夠配置對此 mock 的期望行為並在稍後執行驗證。關於 Spring 提供的核心 AOP 工具,請參考AopUtils和AopProxyUtils這兩個類。

10.2.2 Spring MVC

org.springframework.test.web包含了ModelAndViewAssert類。你可以在用 Junit,TestNG 或任何測試框架編寫的單元測試中使用這個類來幫助你跟 Spring MVC 框架的ModelAndView物件進行互動。

注:如果想要像測試 POJO 一樣來測試你的 Spring MVC 控制器,你可以將ModelAndViewAssert與MockHttpServletRequestMockHttpSession等來自 Servlet API mocks 的 Mock 類結合使用。而假如是要把 Spring MVC 和 REST Controller 與WebApplicationContext配置結合起來進行一番徹底的整合測試,請使用 Spring MVC 測試框架。