來源:https://www.yoodb.com/
首先簡單介紹一下Spring,它是一個輕量級開源框架,簡單的來說,Spring是一個分層的JavaSE/EEfull-stack(一站式) 輕量級開源框架。特點方便解耦,簡化開發,AOP編程的支持聲明式,事務的支持以及降低Java EE API的使用難度等。
目前主流的Web MVC框架除了Struts之外就是SpringMVC,不過要想靈活運用SpringMVC來應對大多說的web開發除了必須掌握其配置和原理外還需要會測試。在Spring3.2版本之前測試一般都是直接new控制器注入依賴進行判斷返回,但無法測試基礎配置參數如攔截器、數據綁定、類型轉換等等。
從Spring3.2版本之后這些都可以完成,並且是測試一個完成的SpringMVC流程。下面為大家分享一下SpringMVC框架中MockMvc注解含義及其原理分析。
SpringJunitTestMock測試類下各個注解/變量的含義如下:
1、下面對各變量/注解進行解釋
@WebAppConfiguration
表明該類會使用web應用程序的默認根目錄來載入ApplicationContext, 默認的更目錄是"src/main/webapp", 如果需要更改這個更目錄可以修改該注釋的value值。
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration(value = "src/main/webapp") @ContextHierarchy({ @ContextConfiguration(name = "parent" ,locations = "classpath:applicationContext.xml"), })
@RunWith
使用 Spring-Test 框架;在使用所有注釋前必須使用@RunWith(SpringJUnit4ClassRunner.class),讓測試運行於Spring測試環境。
@ContextConfiguration(location = ): 指定需要加載的spring配置文件的地址
@Mock: 需要被Mock的對象
@Transactional:不是必須的,是和@TestExecutionListeners中的TransactionalTestExecutionListener.class配合使用,用於保證插入的數據庫中的測試數據,在測試完后,事務回滾,將插入的數據給刪除掉,保證數據庫的干凈。如果沒有顯示的指定@Transactional,那么插入到數據庫中的數據就是真實數據。
@InjectMocks: 需要將Mock對象注入的對象, 此處就是Controller
@Before: 在每次Test方法之前運行的方法,目前把登陸信息放到session中處理,以及初始化mockMvc。
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
@Test:執行測試
基本框架,實例代碼如下圖:

參考資料:http://blog.yoodb.com/yoodb/article/detail/1321
2、具體測試的方法
測試方法中的mockMvc需要調用的方法:
1)mockMvc.perform執行一個請求(該請求由2構造);
2)MockMvcRequestBuilders.get("/user/1")構造一個請求
3)ResultActions.andExpect添加執行完成后的斷言,目的測試返回結果,通過返回結果來確認測試是否成功
4)ResultActions.andDo添加一個結果處理器,表示要對結果做點什么事情,比如此處使用MockMvcResultHandlers.print()輸出整個響應結果信息。
5)ResultActions.andReturn表示執行完成后返回相應的結果。
mockMvc.perform(執行一個請求) (MockMvcRequestBuilders.get("/order/one_orders") //構造一個請求 .session(session) .contentType(MediaType.APPLICATION_XHTML_XML).param("page", "1")) .andExpect(view().name("order/one_orders/index")) //執行完后寫斷言
3、整個測試過程非常有規律:
1)准備測試環境
2)通過MockMvc執行請求
3)添加驗證斷言
4)添加結果處理器
5)得到MvcResult進行自定義斷言/進行下一步的異步請求
4、卸載測試環境
SpringMVC測試框架提供了兩種方式,獨立安裝和集成Web環境測試
1、mockMvc.perform執行一個請求;
2、MockMvcRequestBuilders.get("/user/1")構造一個請求
3、ResultActions.andExpect添加執行完成后的斷言
4、ResultActions.andDo添加一個結果處理器,表示要對結果做點什么事情,比如此處使用MockMvcResultHandlers.print()輸出整個響應結果信息。
5、ResultActions.andReturn表示執行完成后返回相應的結果。
MockMvcBuilder是用來構造MockMvc的構造器,其主要有兩個實現:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,StandaloneMockMvcBuilder繼承了DefaultMockMvcBuilder。
直接使用靜態工廠MockMvcBuilders創建即可:
MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,將會從該上下文獲取相應的控制器並得到相應的MockMvc;
MockMvcBuilders.standaloneSetup(Object... controllers):通過參數指定一組控制器,這樣就不需要從上下文獲取了;
其中DefaultMockMvcBuilder還提供了如下API:
addFilters(Filter... filters)/addFilter(Filter filter, String... urlPatterns):添加javax.servlet.Filter過濾器
defaultRequest(RequestBuilder requestBuilder):默認的RequestBuilder,每次執行時會合並到自定義的RequestBuilder中,即提供公共請求數據的;
alwaysExpect(ResultMatcher resultMatcher):定義全局的結果驗證器,即每次執行請求時都進行驗證的規則;
alwaysDo(ResultHandler resultHandler):定義全局結果處理器,即每次請求時都進行結果處理;
dispatchOptions:DispatcherServlet是否分發OPTIONS請求方法到控制器;
StandaloneMockMvcBuilder繼承了DefaultMockMvcBuilder,又提供了如下API:
setMessageConverters(HttpMessageConverter
setValidator(Validator validator):設置驗證器;
setConversionService(FormattingConversionService conversionService):設置轉換服務;
addInterceptors(HandlerInterceptor... interceptors)/addMappedInterceptors(String[] pathPatterns, HandlerInterceptor... interceptors):添加spring mvc攔截器;
setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager):設置內容協商管理器;
setAsyncRequestTimeout(long timeout):設置異步超時時間;
setCustomArgumentResolvers(HandlerMethodArgumentResolver... argumentResolvers):設置自定義控制器方法參數解析器;
setCustomReturnValueHandlers(HandlerMethodReturnValueHandler... handlers):設置自定義控制器方法返回值處理器;
setHandlerExceptionResolvers(List
setViewResolvers(ViewResolver...resolvers):設置視圖解析器;
setSingleView(View view):設置單個視圖,即視圖解析時總是解析到這一個(僅適用於只有一個視圖的情況);
setLocaleResolver(LocaleResolver localeResolver):設置Local解析器;
setFlashMapManager(FlashMapManager flashMapManager):設置FlashMapManager,如存儲重定向數據;
setUseSuffixPatternMatch(boolean useSuffixPatternMatch):設置是否是后綴模式匹配,如“/user”是否匹配"/user.*",默認真即匹配;
setUseTrailingSlashPatternMatch(boolean useTrailingSlashPatternMatch):設置是否自動后綴路徑模式匹配,如“/user”是否匹配“/user/”,默認真即匹配;
addPlaceHolderValue(String name, String value) :添加request mapping中的占位符替代;
StandaloneMockMvcBuilder不會加載Spring MVC配置文件,因此就不會注冊我們需要的一些組件,因此就提供了如上API用於注冊我們需要的相應組件。
perform:執行一個RequestBuilder請求,會自動執行SpringMVC的流程並映射到相應的控制器執行處理;
andExpect:添加ResultMatcher驗證規則,驗證控制器執行完成后結果是否正確;
andDo:添加ResultHandler結果處理器,比如調試時打印結果到控制台;
andReturn:最后返回相應的MvcResult;然后進行自定義驗證/進行下一步的異步處理;
MockMvcRequestBuilders主要API:
MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables):根據uri模板和uri變量值得到一個GET請求方式
MockHttpServletRequestBuilder;如get("/user/{id}", 1L);
MockHttpServletRequestBuilder post(String urlTemplate, Object... urlVariables):同get類似,但是是POST方法;
MockHttpServletRequestBuilder put(String urlTemplate, Object... urlVariables):同get類似,但是是PUT方法;
MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables) :同get類似,但是是DELETE方法;
MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables):同get類似,但是是OPTIONS方法;
調用MockMvc.perform(RequestBuilder requestBuilder)后,將得到ResultActions:
ResultActions andExpect(ResultMatcher matcher) :添加驗證斷言來判斷執行請求后的結果是否是預期的;
ResultActions andDo(ResultHandler handler) :添加結果處理器,用於對驗證成功后執行的動作,如輸出下請求/結果信息用於調試;
MvcResult andReturn() :返回驗證成功后的MvcResult;用於自定義驗證/下一步的異步處理。
