首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Spring Test 深度指南:從 Mock 對象到事務性集成測試

     編輯:Java 相關知識

Spring 提供豐富的測試支持體系,覆蓋單元級 Mock、集成級上下文緩存、事務性數據庫測試三大場景。本文系統梳理核心類層次、最佳實踐與常見坑點。

Mock 對象體系(單元測試)

位於 org.springframework.mock.*,核心類:

  • MockHttpServletRequest:模擬 HTTP 請求,addParameter、setMethod 等極便利。
  • MockHttpServletResponse:捕獲響應內容、狀態碼、Header。
  • MockHttpSession、MockServletConfig、MockFilterConfig、MockPageContext(可測試預編譯 JSP)。
  • DelegatingServletInputStream/OutputStream:攔截流內容分析。

示例:
MockHttpServletRequest req = new MockHttpServletRequest("POST", "/index.do");
req.addParameter("username", "name");

集成測試抽象基類體系

均在 org.springframework.test 包,繼承關係:

  1. AbstractSpringContextTests:根類,僅提供上下文加載緩存,無自動注入。
  2. AbstractDependencyInjectionSpringContextTests:支持 Setter 注入,必須實現 getConfigLocations() 返回配置路徑數組。
  3. AbstractTransactionalSpringContextTests:在 Spring 管理事務中運行測試,自動回滾,不污染數據庫。
  4. AbstractTransactionalDataSourceSpringContextTests:提供 protected JdbcTemplate jdbcTemplate 直接操作數據庫,適合持久層測試。

配置路徑加載策略

// 基於 classpath(文件需在 WEB-INF/classes 或源碼目錄)
public String[] getConfigLocations() {
    return new String[] {"applicationContext.xml", "hibernate-context.xml"};
}

// 基於文件系統相對路徑(相對於專案根目錄)
public String[] getConfigLocations() {
    return new String[] {"file:WebContent/WEB-INF/applicationContext.xml"};
}

依賴注入機制與多 Bean 同類型處理

  • 單一類型 Bean:定義 Setter,框架自動按類型注入。
  • 多同類型 Bean:自動注入失效,需在 onSetUp() 中顯式 applicationContext.getBean("beanName")。
  • 不需要注入:不寫 Setter 或繼承 AbstractSpringContextTests。

上下文緩存與「髒」上下文處理

框架按 getConfigLocations() 返回數組緩存 Context,大項目啟動一次可節省 10-20 秒。若測試修改了 Bean 定義/狀態,調用 setDirty() 強制下一測試重新加載。

完整示例:事務性 Service 測試

public class ProductManagerTest extends AbstractTransactionalDataSourceSpringContextTests {
    private ProductManager productManager;

    public String[] getConfigLocations() {
        return new String[] {"file:WebContent/WEB-INF/applicationContext.xml"};
    }

    public void setProductManager(ProductManager pm) { this.productManager = pm; }

    public void testGetProduct() {
        assertEquals("tomson", productManager.getProductByName("tomson").getName());
    }
}

避坑指南

  • 確保測試類路徑包含所有 XML 配置與映射文件。
  • 事務性測試要求數據庫支持事務(MyISAM 無效,需 InnoDB)。
  • jdbcTemplate 僅在 AbstractTransactionalDataSourceSpringContextTests 及其子類可用。
  • JUnit 4+ 建議改用 @RunWith(SpringJUnit4ClassRunner.class) + @ContextConfiguration 註解風格,舊基類已標註 Deprecated。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved