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