Struts 曾長期壟斷 Java Web 開發,雖逐漸退出歷史舞台,但成千上萬遺留應用仍在運行。企業寧願測試維護也不願重寫,理解其缺陷並掌握重構測試技巧至關重要。本文聚焦最普遍的 Action 類測試場景。
Struts 將業務邏輯從 Servlet 移入 Action 類,配合 ActionForm 傳遞數據。易上手卻常導致團隊忽視長期設計。開發者測試與代碼複雜度強相關:高複雜難測試,寫測試倒逼簡化設計。Action 類常成複雜性保護所:直接調用 EJB、打開數據庫連接、耦合 HttpServletRequest/Response,極難隔離測試(圖 1)。

即使簡單的 ChangePasswordAction.execute()(清單 1),隔離測試也需處理:Struts 框架耦合、Servlet API 耦合、業務對象包耦合(進而牽涉 Hibernate/Spring 數據層)。Mock 對象雖能隔離,但構建成本極高。更高層次的集成測試更務實。ActionForm.validate() 邏輯(清單 2)進一步增加複雜性。
StrutsTestCase 是 JUnit 擴展,模擬 Servlet 容器虛擬運行 Struts 應用,無需 Tomcat。MockStrutsTestCase 處理配置加載(struts-config.xml)。需指向 Web 應用目錄、web.xml、struts-config.xml(清單 3-4 目錄結構與配置代碼)。
測試通過路徑映射間接調用 Action。struts-config.xml 映射 /changePasswordSubmit 到 ChangePasswordAction(清單 5)。JSP 表單參數(username、currentPassword、newPassword1/2)映射到請求參數。清單 6 驗證口令修改成功:設置路徑、參數、執行 actionPerform()、驗證 success 轉發。
僅驗證轉發不夠,需數據庫層驗證且可重複。DbUnit 通過 XML 種子文件建立已知數據庫狀態(清單 7),DatabaseOperation.CLEAN_INSERT 保證乾淨數據集(清單 8 fixture 邏輯)。測試用例驗證數據庫口令更新(清單 9-10 verifyPassword() 使用 DbUnit 查詢 API 比較 XML)。
清單 11 整合:DbUnit 填充數據、配置 Struts、調用 Action/Form、參數映射、驗證轉發、驗證數據庫。清單 12 補充邊界測試:密碼不匹配時驗證 ActionError 且數據庫未變。verifyActionErrors() 斷言錯誤條件。
Struts 應用不會快速消失,掌握開發者測試構建保證層必不可少。StrutsTestCase 處理框架,DbUnit 處理數據庫,兩者結合實現集成級測試,無需瀏覽器模擬(JWebUnit/Selenium 另當別論)。測試 Struts 雖費力,但完全可行。