背景:
我們在使用Spring集成的項目進行開發的時候,需要在不依賴web容器啓動的時候去進行單元測試,而Spring爲我們提供了相應單元測試框架,在spring
的org.springframework.test.context包內,我們只要在單元測試中引入相應的註解,就可以輕鬆的實現單元測試。其實好的單元測試可以大大提高我們的生產力,加快我們的開發速度。
使用方法
下圖是我自己寫的一個測試類的方法。
使用很簡單
1)加入Junit4的註解 @RunWith,在這裏可以指定Spring的的運行器來集成。
2)加入@ContextConfiguration註解,指定要加載的配置文件的位置。
如果我們想基於實務的測試,繼承AbstractTransactionalJUnit4SpringContextTests
提示:常用的做法是我們寫一個公共的父類來加載配置文件,其他的單元測試來繼承這個類即可。
原理解析
Spring的主要測試框架的核心是TestContext,TestContextManager,TestExcutionListener接口,我們每次啓動測試的時候都會創建TestContextManager,它實際上是管理了一個TestContext來負責持有一個當前測試的上下文,可以實現測試實例的依賴注入。TestContextManager還負責在測試中更新TestContext的狀態並代理到TestExecutionListener,它是用來監控實際的執行(如依賴注入,管理實務等等)
下面我們來看下Spring的源代碼來看下執行單元測試時候Spring是如何工作的
看TestContext的調用棧不難看出,執行SpringJUnit4ClassRunner的createTestContextManager來創建 TestContextManager
在創建TestContext的時候,我們看下構造方法,關鍵的兩步,首先解析測試類的註解,其次創建ContextLoader
以上是Spring框架的前期準備工作,完成TestContext的屬性的配置,那麼接下來Spring真正實現上下文加載是在重寫了Junit4 中BlockJUnit4ClassRunner的methodBlock方法。
然後實現依賴注入等相關操作
總結:
Spring的基於註解的單元測試確實方便了我們的測試和開發啊,我們在不啓動web容器的時候,可以對我們的Service層代碼進行單元測試,具體Spring的單元測試還有很多的高級用法,大家有興趣可以看下,比如@TestExecutionListeners:這個用於指定在測試類執行之前,可以做的一些動作,如這裏的DependencyInjectionTestExecutionListener.class,就可以對一測試類中的依賴進行注入,TransactionalTestExecutionListener.class用於對事務進行管理;這兩個都是Srping自帶的;我們也可以實現自己的Listener類來完成我們自己的操作,只需要繼續類org.springframework.test.context.support.AbstractTestExecutionListener就可以了