MockMvc 與端到端測試
MockMvc 是基於 spring-test 模組中的 Servlet API 模擬實現構建的,不依賴於執行中的容器。因此,與實際客戶端和執行中的真實伺服器進行完整的端到端整合測試相比,存在一些差異。
最簡單的理解方式是,從一個空白的 MockHttpServletRequest 開始。你新增的任何內容都將成為請求。可能會讓你感到驚訝的是,預設情況下沒有上下文路徑;沒有 jsessionid cookie;沒有轉發、錯誤或非同步排程;因此,也沒有實際的 JSP 渲染。相反,"轉發"和"重定向"的 URL 會儲存在 MockHttpServletResponse 中,並且可以透過期望進行斷言。
這意味著,如果你使用 JSP,你可以驗證請求轉發到的 JSP 頁面,但不會渲染 HTML。換句話說,JSP 不會被呼叫。但是,請注意,所有不依賴於轉發的其他渲染技術,例如 Thymeleaf 和 Freemarker,都會按預期將 HTML 渲染到響應體中。透過 @ResponseBody 方法渲染 JSON、XML 和其他格式也是如此。
或者,你可以考慮使用 Spring Boot 提供的 @SpringBootTest 進行完整的端到端整合測試支援。請參閱 Spring Boot 參考指南。
每種方法都有其優缺點。Spring MVC Test 中提供的選項是經典單元測試到完全整合測試之間的一個個停靠點。可以肯定的是,Spring MVC Test 中的任何選項都不屬於經典單元測試的範疇,但它們更接近於經典單元測試。例如,你可以透過將模擬服務注入到控制器中來隔離 Web 層,在這種情況下,你僅透過 DispatcherServlet 測試 Web 層,但使用實際的 Spring 配置,就像你可以在隔離於其上層的情況下測試資料訪問層一樣。此外,你可以使用獨立設定,一次只關注一個控制器,並手動提供使其工作所需的配置。
使用 Spring MVC Test 的另一個重要區別是,從概念上講,此類測試是伺服器端測試,因此你可以檢查使用了哪個處理器,是否使用 HandlerExceptionResolver 處理了異常,模型的內容是什麼,存在哪些繫結錯誤以及其他詳細資訊。這意味著更容易編寫期望,因為伺服器不是一個不透明的盒子,不像透過實際 HTTP 客戶端測試時那樣。這通常是經典單元測試的優勢:它更容易編寫、推理和除錯,但不能取代對完整整合測試的需求。同時,重要的是不要忽視響應是最重要的事情。簡而言之,即使在同一個專案中,也有多種測試風格和策略的餘地。