MockMvc vs 端對端測試
MockMvc 建構於來自 spring-test
模組的 Servlet API mock 實作之上,並不依賴於運行的容器。因此,與使用實際客户端和運行的伺服器進行完整的端對端整合測試相比,存在一些差異。
最容易理解這一點的方式是從一個空白的 MockHttpServletRequest
開始。您添加到其中的任何內容都會成為請求。可能讓您感到驚訝的事情是,預設情況下沒有 context path;沒有 jsessionid
cookie;沒有轉發、錯誤或非同步分派;因此,也沒有實際的 JSP 渲染。相反,「轉發」和「重新導向」的 URL 會保存在 MockHttpServletResponse
中,並且可以使用期望進行斷言。
這表示,如果您使用 JSP,您可以驗證請求轉發到的 JSP 頁面,但不會渲染 HTML。換句話說,JSP 不會被調用。但是請注意,所有其他不依賴轉發的渲染技術,例如 Thymeleaf 和 Freemarker,都會如預期般將 HTML 渲染到回應 body 中。對於透過 @ResponseBody
方法渲染 JSON、XML 和其他格式也是如此。
或者,您可以考慮 Spring Boot 提供的完整端對端整合測試支援,使用 @SpringBootTest
。請參閱 Spring Boot 參考指南。
每種方法都有優缺點。Spring MVC Test 中提供的選項在從傳統單元測試到完整整合測試的範圍內提供了不同的停靠點。可以肯定的是,Spring MVC Test 中的任何選項都不屬於傳統單元測試的範疇,但它們更接近於單元測試。例如,您可以透過將 mock 服務注入控制器來隔離 Web 層,在這種情況下,您僅透過 DispatcherServlet
測試 Web 層,但使用實際的 Spring 組態,就像您可能將資料存取層與其上層隔離測試一樣。此外,您可以使用獨立設定,一次專注於一個控制器,並手動提供使其運作所需的組態。
使用 Spring MVC Test 時,另一個重要的區別是,從概念上講,此類測試是伺服器端測試,因此您可以檢查使用了哪個處理器、是否使用 HandlerExceptionResolver
處理了例外、模型的內容是什麼、存在哪些綁定錯誤以及其他詳細資訊。這意味著編寫期望更容易,因為伺服器不是一個不透明的黑盒子,就像透過實際的 HTTP 客户端進行測試時一樣。這通常是傳統單元測試的一個優點:它更容易編寫、推理和偵錯,但不能取代對完整整合測試的需求。同時,重要的是不要忽略回應是最重要的檢查項目這一事實。簡而言之,即使在同一個專案中,也存在多種測試樣式和策略的空間。