Spring Testing

單位測試

依賴注入應該使您的代碼在容器上的依賴性要低於傳統的Java EE開發。構成應用程序的POJO應該在JUnit或TestNG測試中可測試,使用new操作符簡單地實例化對象,而不使用Spring或任何其他容器。您可以使用模擬對象(結合其他有價值的測試技術)來隔離測試代碼。如果您遵循Spring的架構建議,您的代碼庫的乾淨分層和組件化將有助於簡化單元測試。例如,您可以通過存根或模擬DAO或Repository接口來測試服務層對象,而無需在運行單元測試時訪問持久性數據。

真正的單元測試通常運行得非常快,因爲沒有運行時基礎架構來設置。強調真正的單元測試作爲開發方法的一部分將提高您的生產力。您可能不需要測試章節的這一部分來幫助您爲基於IoC的應用程序編寫有效的單元測試。但是,對於某些單元測試場景,Spring Framework提供了以下模擬對象和測試支持類。

模擬對象

環境

org.springframework.mock.env包包含了EnvironmentPropertySource抽象的模擬實現(見“Bean定義配置文件”和“PropertySource抽象”)。MockEnvironmentMockPropertySource可用於開發針對依賴環境特性的代碼的容器外測試。

JNDI

org.springframework.mock.jndi包中包含一個JNDI SPI的實現,您可以使用它爲測試套件或獨立應用程序設置簡單的JNDI環境。例如,JDBCDataSources在測試代碼中綁定到與Java EE容器中相同的JNDI名稱,您可以在測試場景中重用應用程序代碼和配置,而無需修改。

Servlet API

org.springframework.mock.web軟件包包含一套全面的Servlet API模擬對象,可用於測試Web上下文,控制器和過濾器。這些mock對象的目標是使用Spring的Web MVC框架,並且通常比動態模擬對象(如EasyMock)或替代的Servlet API模擬對象(如MockObjects)更方便使用。從Spring Framework 4.0起,org.springframework.mock.web包中的mocks集合基於Servlet 3.0 API。

有關Spring MVC和REST控制器的完整集成測試以及Spring MVC的WebApplicationContext配置,請參閱Spring MVC測試框架

Portlet API

org.springframework.mock.web.portlet包包含一組Portlet API模擬對象,目標是使用Spring的Portlet MVC框架。

單元測試支持類

通用測試工具

org.springframework.test.util包包含用於單元和集成測試的幾個通用實用工具。

ReflectionTestUtils是基於反射的實用方法的集合。開發人員使用這些方法在以下測試場景中:需要改變常量的值,設置非public字段,調用非publicsetter方法,或者在測試涉及use cases的應用程序代碼時調用非public配置或生命週期回調方法,如下所示。

  • ORM框架,如JPA和Hibernate,它允許privateprotected的字段訪問,而不是域實體中的屬性的publicsetter方法。
  • Spring支持@Autowired@Inject@Resource等註釋,爲privateprotected的字段提供依賴注入,setter方法和配置方法。
  • 使用註釋(如@PostConstruct@PreDestroy)來進行生命週期回調方法。

AopTestUtils是與AOP相關的實用方法的集合。這些方法可用於獲取對一個或多個Spring代理隱藏的底層目標對象的引用。例如,如果您使用類似EasyMock或Mockito的庫將Bean配置爲動態模擬,
並將模擬包裝在Spring代理中,您可能需要直接訪問底層模擬,才能對其進行預期並執行驗證。對於Spring的核心AOP實用程序,請參閱AopUtilsAopProxyUtils

Spring MVC

org.springframework.test.web包包含ModelAndViewAssert,您可以結合使用JUnit,TestNG或任何其他測試框架來處理Spring MVC ModelAndView對象的單元測試。

要將Spring MVC控制器單元測試爲POJO,請使用ModelAndViewAssert與Spring的Servlet API mocks中的MockHttpServletRequestMockHttpSession等組合。爲了將Spring MVC和REST控制器與Spring MVC的WebApplicationContext配置結合進行徹底集成測試,請改用Spring MVC測試框架

集成測試

概貌

能夠執行一些集成測試,而不需要部署到應用服務器或連接到其他企業基礎架構,這一點非常重要。這將使您能夠測試以下內容:

  • 您的Spring IoC容器上下文的正確連接。
  • 使用JDBC或ORM工具進行數據訪問。這將包括SQL語句,Hibernate查詢,JPA實體映射等的正確性。

Spring框架爲spring-test模塊中的集成測試提供了一流的支持。實際的JAR文件的名稱可能包括髮行版本,也可能在longorg.springframework.test表單中,具體取決於您從哪裏獲取(參見“依賴關係管理”一節進行說明)。該庫包括
org.springframework.test包,它包含用於使用Spring容器進行集成測試的有價值的類。此測試不依賴於應用程序服務器或其他部署環境。這些測試比單元測試運行速度更慢,但比依賴於部署到應用服務器的等效Selenium測試或遠程測試快得多。

在Spring 2.5及更高版本中,單元和集成測試支持以註解驅動的Spring TestContext框架的形式提供。TestContext框架與使用中的實際測試框架無關,因此允許在各種環境中進行測試,包括JUnit,TestNG等。

集成測試目標

Spring的集成測試支持有以下主要目標:

接下來的幾節將描述每個目標,並提供實現和配置詳細信息的鏈接。

上下文管理和緩存

Spring TestContext框架提供了Spring ApplicationContextsWebApplicationContexts的一致加載以及這些上下文的緩存。支持緩存加載的上下文很重要,因爲啓動時間可能會成爲問題 – 不是因爲Spring本身的開銷,而是由於Spring容器實例化的對象需要時間來實例化。例如,具有50到100個Hibernate映射文件的項目可能需要10到20秒才能加載映射文件,並且在每個測試夾具中運行每個測試之前產生該成本導致整體測試運行較慢,從而降低開發人員的生產力。

測試類通常爲XML或Groovy配置元數據(通常在類路徑中)聲明資源位置數組,或者用於配置應用程序的註解類數組。這些位置或類與web.xml或生產部署的其他配置文件中指定的位置或類相同或相似。

默認情況下,一旦加載,配置的ApplicationContext將重新用於每個測試。因此,每個測試套件的安裝成本僅發生一次,後續的測試執行速度要快得多。在這種情況下,術語測試套件意味着所有測試都運行在相同的JVM中 - 例如,所有測試都從給定項目或模塊的Ant,Maven或Gradle構建運行。在不太可能的情況下,測試會破壞應用程序上下文並需要重新加載 – 例如,通過修改bean定義或應用程序對象的狀態 - 可以配置TestContext框架以在執行下一個測試之前重新加載配置並重新構建應用程序上下文。

參見第“上下文管理”和TestContext框架的“上下文緩存”一節。

測試夾具的依賴注入

當TestContext框架加載您的應用程序上下文時,它可以選擇通過依賴注入來配置測試類的實例。這提供了一種方便的機制,可以使用來自應用程序上下文的預配置的bean設置測試夾具。這裏的一大優點是您可以在各種測試場景(例如,配置Spring管理的對象圖,事務代理,DataSources等)中重用應用程序上下文,從而避免了複雜的測試夾具對於各個測試用例的複製。

例如,考慮我們有一個類HibernateTitleRepository,它爲Title域實體實現數據訪問邏輯的場景。我們想要編寫測試以下幾個方面的集成測試:

  • Spring配置:基本上是與HibernateTitleRepository bean的配置有關的一切是否正確?
  • Hibernate映射文件配置:是否正確映射了所有映射,並且是正確的延遲加載設置嗎?
  • HibernateTitleRepository的邏輯:此類的配置實例是否按預期方式執行?

請參閱TestContext框架的依賴注入測試夾具。

事務管理

訪問真實數據庫的測試中的一個常見問題是它們對持久性存儲的狀態的影響。即使在使用開發數據庫時,狀態的更改可能會影響未來的測試。此外,許多操作(例如插入或修改持久性數據)不能在事務之外執行(或驗證)。

TestContext框架解決了這個問題。默認情況下,框架將爲每個測試創建並回滾一個事務。你只需編寫一個可以承擔事務存在的代碼。如果您在測試中調用事務代理的對象,則它們將根據其配置的事務語義正確執行。
另外,如果測試方法在爲測試管理的事務中運行時刪除所選表的內容,則事務將默認回滾,並且數據庫將返回到執行測試之前的狀態。事件支持通過測試應用程序上下文中定義的PlatformTransactionManager bean提供給測試。

如果你想要一個事務提交 – 不常見的,但是當您想要特定的測試來填充或修改數據庫時,偶爾會很有用 – 可以指示TestContext框架通過@Commit註釋導致事務提交而不是回滾。

請參閱TestContext framework的事務管理。

集成測試支持類

Spring TestContext框架提供了幾個抽象支持類,簡化了集成測試的編寫。這些基礎測試類爲測試框架提供了明確的鉤子,以及方便的實例變量和方法,使您能夠訪問:

  • ApplicationContext用於執行顯式bean查找或測試整個上下文的狀態。
  • 一個JdbcTemplate,用於執行SQL語句來查詢數據庫。這樣的查詢可以在執行數據庫相關應用程序代碼之前和之後用於確認數據庫狀態,而且Spring可以確保這些查詢在與應用程序代碼相同的事務的範圍內運行。當與ORM工具結合使用時,請務必避免誤報

此外,您可能希望創建自己的自定義應用程序範圍的超類與實例變量和特定於您的項目的方法。

請參閱TestContext框架的支持類。

JDBC測試支持

org.springframework.test.jdbc包包含JdbcTestUtils,它是用於簡化標準數據庫測試場景的JDBC相關實用程序函數的集合。具體來說,JdbcTestUtils提供了以下靜態實用程序方法。

  • countRowsInTable(..): 計算給定表中的行數
  • countRowsInTableWhere(..): 使用提供的WHERE子句來計算給定表中的行數
  • deleteFromTables(..): 從指定的表中刪除所有行
  • deleteFromTableWhere(..): 使用提供的WHERE子句從給定的表中刪除行
  • dropTables(..): 刪除指定的表

請注意,AbstractTransactionalJUnit4SpringContextTestsAbstractTransactionalTestNGSpringContextTests提供了在JdbcTestUtils中委派給上述方法的便利方法。

spring-jdbc模塊支持配置和啓動可與數據庫交互的集成測試中使用的嵌入式數據庫。
有關詳細信息,請參見“嵌入式數據庫支持”和“使用嵌入式數據庫測試數據訪問邏輯

註解

Spring測試註解

Spring框架提供了以下一組特定於Spring的註釋,您可以在單元中使用該註解,並結合TestContext框架進行集成測試。有關更多信息,請參閱相應的javadocs,包括默認屬性值,屬性別名等。

……

參考鏈接: spring testing

發佈了103 篇原創文章 · 獲贊 19 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章