單元測試
依賴注入應該讓你的程式碼對容器的依賴程度低於傳統的 J2EE / Java EE 開發。組成你應用的 POJO 應該可以在 JUnit 或 TestNG 測試中進行測試,透過使用 new
運算子例項化物件,而無需 Spring 或任何其他容器。你可以使用 mock 物件(結合其他有價值的測試技術)來隔離地測試你的程式碼。如果你遵循 Spring 的架構建議,由此產生的清晰分層和程式碼庫元件化有助於更輕鬆地進行單元測試。例如,你可以透過 stub 或 mock DAO 或 repository 介面來測試服務層物件,而無需在執行單元測試時訪問持久化資料。
真正的單元測試通常執行速度非常快,因為不需要設定執行時基礎設施。將真正的單元測試作為開發方法的一部分來強調可以提高你的生產力。你可能不需要測試章節的這一部分來幫助你為基於 IoC 的應用程式編寫有效的單元測試。然而,對於某些單元測試場景,Spring Framework 提供了 mock 物件和測試支援類,本章對此進行了描述。
Mock 物件
Spring 包含了許多專門用於 mock 的包
環境
org.springframework.mock.env
包包含了 Environment
和 PropertySource
抽象的 mock 實現(參見 Bean 定義 Profile 和 PropertySource
抽象)。MockEnvironment
和 MockPropertySource
對於開發依賴於特定環境屬性的程式碼的容器外測試非常有用。
Servlet API
org.springframework.mock.web
包包含了一整套 Servlet API mock 物件,這些物件對於測試 web 上下文、控制器和過濾器非常有用。這些 mock 物件主要用於 Spring 的 Web MVC 框架,並且通常比動態 mock 物件(例如 EasyMock)更方便使用。
自 Spring Framework 6.0 起,org.springframework.mock.web 中的 mock 物件基於 Servlet 6.0 API。 |
MockMvc 基於 mock Servlet API 物件構建,為 Spring MVC 提供了一個整合測試框架。參見 MockMvc。
Spring Web Reactive
org.springframework.mock.http.server.reactive
包包含了用於 WebFlux 應用程式的 ServerHttpRequest
和 ServerHttpResponse
的 mock 實現。org.springframework.mock.web.server
包包含了依賴於這些 mock 請求和響應物件的 mock ServerWebExchange
。
MockServerHttpRequest
和 MockServerHttpResponse
都繼承自與伺服器特定實現相同的抽象基類,並與它們共享行為。例如,mock 請求一旦建立就不可變,但你可以使用 ServerHttpRequest
中的 mutate()
方法建立一個修改後的例項。
為了使 mock 響應能夠正確實現寫入契約並返回寫入完成控制代碼(即 Mono<Void>
),它預設使用帶有 cache().then()
的 Flux
,這會緩衝資料並使其在測試中可用於斷言。應用程式可以設定自定義寫入函式(例如,用於測試無限流)。
WebTestClient 基於 mock 請求和響應構建,為測試 WebFlux 應用提供支援,而無需 HTTP 伺服器。該客戶端也可用於與執行中的伺服器進行端到端測試。
單元測試支援類
Spring 包含許多有助於單元測試的類。它們分為兩類:
通用測試工具
org.springframework.test.util
包包含了一些用於單元測試和整合測試的通用工具類。
AopTestUtils
是一系列與 AOP 相關的工具方法集合。你可以使用這些方法獲取隱藏在一個或多個 Spring 代理背後的底層目標物件的引用。例如,如果你使用 EasyMock 或 Mockito 等庫將一個 bean 配置為動態 mock,並且該 mock 被包裝在 Spring 代理中,你可能需要直接訪問底層 mock 來配置其期望並執行驗證。對於 Spring 的核心 AOP 工具類,請參見 AopUtils
和 AopProxyUtils
。
ReflectionTestUtils
是一系列基於反射的工具方法集合。在以下應用場景中測試應用程式碼時,如果你需要更改常量的值、設定非 public
欄位、呼叫非 public
setter 方法或呼叫非 public
配置或生命週期回撥方法,可以使用這些方法:
-
支援
private
或protected
欄位訪問(而非public
setter 方法)來訪問領域實體屬性的 ORM 框架(例如 JPA 和 Hibernate)。 -
Spring 對註解(例如
@Autowired
、@Inject
和@Resource
)的支援,這些註解為private
或protected
欄位、setter 方法和配置方法提供依賴注入。 -
使用
@PostConstruct
和@PreDestroy
等註解作為生命週期回撥方法。
TestSocketUtils
是一個簡單的工具類,用於在整合測試場景中查詢 localhost
上可用的 TCP 埠。
|
Spring MVC 測試工具
org.springframework.test.web
包包含 ModelAndViewAssert
,你可以將其與 JUnit、TestNG 或任何其他測試框架結合使用,用於處理 Spring MVC ModelAndView
物件的單元測試。
單元測試 Spring MVC 控制器 要將你的 Spring MVC Controller 類作為 POJO 進行單元測試,請結合使用 ModelAndViewAssert 和 Spring 的 Servlet API mocks 中的 MockHttpServletRequest 、MockHttpSession 等。要對你的 Spring MVC 和 REST Controller 類以及 Spring MVC 的 WebApplicationContext 配置進行全面的整合測試,請改為使用 MockMvc。 |