SpringMVC 測試 mockMVC

?

SpringMVC測試框架

基于RESTful風格的SpringMVC的測試,我們可以測試完整的Spring MVC流程,即從URL請求到控制器處理,再到視圖渲染都可以測試。

一 MockMvcBuilder

MockMvcBuilder是用來構造MockMvc的構造器,其主要有兩個實現:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,分別對應兩種測試方式,即獨立安裝和集成Web環境測試(此種方式并不會集成真正的web環境,而是通過相應的Mock API進行模擬測試,無須啟動服務器)。對于我們來說直接使用靜態工廠MockMvcBuilders創建即可。

1.集成Web環境方式

MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,將會從該上下文獲取相應的控制器并得到相應的MockMvc;

復制代碼
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:config/IncotermsRestServiceTest-context.xml")
@WebAppConfiguration
public class IncotermsRestServiceTest {@Autowiredprivate WebApplicationContext wac;private MockMvc mockMvc;@Beforepublic void setup() {this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();   //構造MockMvc}...
}
復制代碼

注意:
(1)@WebAppConfiguration:測試環境使用,用來表示測試環境使用的ApplicationContext將是WebApplicationContext類型的;value指定web應用的根;
(2)通過@Autowired WebApplicationContext wac:注入web環境的ApplicationContext容器;
(3)然后通過MockMvcBuilders.webAppContextSetup(wac).build()創建一個MockMvc進行測試;

2.獨立測試方式

MockMvcBuilders.standaloneSetup(Object... controllers):通過參數指定一組控制器,這樣就不需要從上下文獲取了;

復制代碼
public class PricingExportResultsRestServiceTest {@InjectMocksprivate PricingExportResultsRestService pricingExportResultsRestService;@Mockprivate ExportRateScheduleService exportRateScheduleService;@Mockprivate PricingUrlProvider pricingUrlProvider;private MockMvc mockMvc;@Beforepublic void setup() {MockitoAnnotations.initMocks(this);mockMvc = MockMvcBuilders.standaloneSetup(pricingExportResultsRestService).build();  //構造MockMvc}...
}
復制代碼

主要是兩個步驟:
(1)首先自己創建相應的控制器,注入相應的依賴
(2)通過MockMvcBuilders.standaloneSetup模擬一個Mvc測試環境,通過build得到一個MockMvc

?

二 MockMvc

先看一個測試例子1:

復制代碼
  @Testpublic void createIncotermSuccess() throws Exception {IncotermTo createdIncoterm = new IncotermTo();createdIncoterm.setId(new IncotermId(UUID.fromString("6305ff33-295e-11e5-ae37-54ee7534021a")));createdIncoterm.setCode("EXW");createdIncoterm.setDescription("code exw");createdIncoterm.setLocationQualifier(LocationQualifier.DEPARTURE);when(inventoryService.create(any(IncotermTo.class))).thenReturn(createdIncoterm);mockMvc.perform(post("/secured/resources/incoterms/create").accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON).content("{\"code\" : \"EXW\", \"description\" : \"code exw\", \"locationQualifier\" : \"DEPARTURE\"}".getBytes()))//.andDo(print()).andExpect(status().isOk()).andExpect(jsonPath("id.value").exists()).andExpect(jsonPath("id.value").value("6305ff33-295e-11e5-ae37-54ee7534021a")).andExpect(jsonPath("code").value("EXW"));}
復制代碼

perform:執行一個RequestBuilder請求,會自動執行SpringMVC的流程并映射到相應的控制器執行處理;
andExpect:添加ResultMatcher驗證規則,驗證控制器執行完成后結果是否正確;
andDo:添加ResultHandler結果處理器,比如調試時打印結果到控制臺;
andReturn:最后返回相應的MvcResult;然后進行自定義驗證/進行下一步的異步處理;

?

看一個具體的例子2:

復制代碼
    @Test  public void testView() throws Exception {  MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/user/1"))  .andExpect(MockMvcResultMatchers.view().name("user/view"))  .andExpect(MockMvcResultMatchers.model().attributeExists("user"))  .andDo(MockMvcResultHandlers.print())  .andReturn();  Assert.assertNotNull(result.getModelAndView().getModel().get("user"));  }  
復制代碼

整個過程:
1、mockMvc.perform執行一個請求;
2、MockMvcRequestBuilders.get("/user/1")構造一個請求
3、ResultActions.andExpect添加執行完成后的斷言
4、ResultActions.andDo添加一個結果處理器,表示要對結果做點什么事情,比如此處使用MockMvcResultHandlers.print()輸出整個響應結果信息。
5、ResultActions.andReturn表示執行完成后返回相應的結果。

整個測試過程非常有規律:
1、準備測試環境
2、通過MockMvc執行請求
3.1、添加驗證斷言
3.2、添加結果處理器
3.3、得到MvcResult進行自定義斷言/進行下一步的異步請求
4、卸載測試環境

?

三 RequestBuilder/MockMvcRequestBuilders

從名字可以看出,RequestBuilder用來構建請求的,其提供了一個方法buildRequest(ServletContext servletContext)用于構建MockHttpServletRequest;其主要有兩個子類MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder(如文件上傳使用),即用來Mock客戶端請求需要的所有數據。

1.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方法;
MockHttpServletRequestBuilder request(HttpMethod httpMethod, String urlTemplate, Object... urlVariables): 提供自己的Http請求方法及uri模板和uri變量,如上API都是委托給這個API;
MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object... urlVariables):提供文件上傳方式的請求,得到MockMultipartHttpServletRequestBuilder;
RequestBuilder asyncDispatch(final MvcResult mvcResult):創建一個從啟動異步處理的請求的MvcResult進行異步分派的RequestBuilder;

2.MockHttpServletRequestBuilder和MockMultipartHttpServletRequestBuilder API

(1)MockHttpServletRequestBuilder API

MockHttpServletRequestBuilder header(String name, Object... values)/MockHttpServletRequestBuilder headers(HttpHeaders httpHeaders):添加頭信息;
MockHttpServletRequestBuilder contentType(MediaType mediaType):指定請求的contentType頭信息;
MockHttpServletRequestBuilder accept(MediaType... mediaTypes)/MockHttpServletRequestBuilder accept(String... mediaTypes):指定請求的Accept頭信息;
MockHttpServletRequestBuilder content(byte[] content)/MockHttpServletRequestBuilder content(String content):指定請求Body體內容;
MockHttpServletRequestBuilder cookie(Cookie... cookies):指定請求的Cookie;
MockHttpServletRequestBuilder locale(Locale locale):指定請求的Locale;
MockHttpServletRequestBuilder characterEncoding(String encoding):指定請求字符編碼;
MockHttpServletRequestBuilder requestAttr(String name, Object value) :設置請求屬性數據;
MockHttpServletRequestBuilder sessionAttr(String name, Object value)/MockHttpServletRequestBuilder sessionAttrs(Map<string, object=""> sessionAttributes):設置請求session屬性數據;
MockHttpServletRequestBuilder flashAttr(String name, Object value)/MockHttpServletRequestBuilder flashAttrs(Map<string, object=""> flashAttributes):指定請求的flash信息,比如重定向后的屬性信息;
MockHttpServletRequestBuilder session(MockHttpSession session) :指定請求的Session;
MockHttpServletRequestBuilder principal(Principal principal) :指定請求的Principal;
MockHttpServletRequestBuilder contextPath(String contextPath) :指定請求的上下文路徑,必須以“/”開頭,且不能以“/”結尾;
MockHttpServletRequestBuilder pathInfo(String pathInfo) :請求的路徑信息,必須以“/”開頭;
MockHttpServletRequestBuilder secure(boolean secure):請求是否使用安全通道;
MockHttpServletRequestBuilder with(RequestPostProcessor postProcessor):請求的后處理器,用于自定義一些請求處理的擴展點;

(2)MockMultipartHttpServletRequestBuilder繼承自MockHttpServletRequestBuilder,又提供了如下API

MockMultipartHttpServletRequestBuilder file(String name, byte[] content)/MockMultipartHttpServletRequestBuilder file(MockMultipartFile file):指定要上傳的文件;

?

四 ResultActions

調用MockMvc.perform(RequestBuilder requestBuilder)后將得到ResultActions,通過ResultActions完成如下三件事:
ResultActions andExpect(ResultMatcher matcher) :添加驗證斷言來判斷執行請求后的結果是否是預期的;
ResultActions andDo(ResultHandler handler) :添加結果處理器,用于對驗證成功后執行的動作,如輸出下請求/結果信息用于調試;
MvcResult andReturn() :返回驗證成功后的MvcResult;用于自定義驗證/下一步的異步處理;

?

五 ResultMatcher/MockMvcResultMatchers

1.ResultMatcher用來匹配執行完請求后的結果驗證,其就一個match(MvcResult result)斷言方法,如果匹配失敗將拋出相應的異常;spring mvc測試框架提供了很多***ResultMatchers來滿足測試需求。注意這些***ResultMatchers并不是ResultMatcher的子類,而是返回ResultMatcher實例的。Spring mvc測試框架為了測試方便提供了MockMvcResultMatchers靜態工廠方法方便操作;

2.具體的API如下:
HandlerResultMatchers handler():請求的Handler驗證器,比如驗證處理器類型/方法名;此處的Handler其實就是處理請求的控制器;
RequestResultMatchers request():得到RequestResultMatchers驗證器;
ModelResultMatchers model():得到模型驗證器;
ViewResultMatchers view():得到視圖驗證器;
FlashAttributeResultMatchers flash():得到Flash屬性驗證;
StatusResultMatchers status():得到響應狀態驗證器;
HeaderResultMatchers header():得到響應Header驗證器;
CookieResultMatchers cookie():得到響應Cookie驗證器;
ContentResultMatchers content():得到響應內容驗證器;
JsonPathResultMatchers jsonPath(String expression, Object ... args)/ResultMatcher jsonPath(String expression, Matcher matcher):得到Json表達式驗證器;
XpathResultMatchers xpath(String expression, Object... args)/XpathResultMatchers xpath(String expression, Map<string, string=""> namespaces, Object... args):得到Xpath表達式驗證器;
ResultMatcher forwardedUrl(final String expectedUrl):驗證處理完請求后轉發的url(絕對匹配);
ResultMatcher forwardedUrlPattern(final String urlPattern):驗證處理完請求后轉發的url(Ant風格模式匹配,@since spring4);
ResultMatcher redirectedUrl(final String expectedUrl):驗證處理完請求后重定向的url(絕對匹配);
ResultMatcher redirectedUrlPattern(final String expectedUrl):驗證處理完請求后重定向的url(Ant風格模式匹配,@since spring4);

?

六 一些常用的測試

1.測試普通控制器

mockMvc.perform(get("/user/{id}", 1)) //執行請求  .andExpect(model().attributeExists("user")) //驗證存儲模型數據  .andExpect(view().name("user/view")) //驗證viewName  .andExpect(forwardedUrl("/WEB-INF/jsp/user/view.jsp"))//驗證視圖渲染時forward到的jsp  .andExpect(status().isOk())//驗證狀態碼  .andDo(print()); //輸出MvcResult到控制臺

?

2.得到MvcResult自定義驗證

MvcResult result = mockMvc.perform(get("/user/{id}", 1))//執行請求  .andReturn(); //返回MvcResult  
Assert.assertNotNull(result.getModelAndView().getModel().get("user")); //自定義斷言   

?

3.驗證請求參數綁定到模型數據及Flash屬性

mockMvc.perform(post("/user").param("name", "zhang")) //執行傳遞參數的POST請求(也可以post("/user?name=zhang"))  .andExpect(handler().handlerType(UserController.class)) //驗證執行的控制器類型  .andExpect(handler().methodName("create")) //驗證執行的控制器方法名  .andExpect(model().hasNoErrors()) //驗證頁面沒有錯誤  .andExpect(flash().attributeExists("success")) //驗證存在flash屬性  .andExpect(view().name("redirect:/user")); //驗證視圖  

?

4.文件上傳

byte[] bytes = new byte[] {1, 2};  
mockMvc.perform(fileUpload("/user/{id}/icon", 1L).file("icon", bytes)) //執行文件上傳  .andExpect(model().attribute("icon", bytes)) //驗證屬性相等性  .andExpect(view().name("success")); //驗證視圖  

?

5.JSON請求/響應驗證

復制代碼
String requestBody = "{\"id\":1, \"name\":\"zhang\"}";  mockMvc.perform(post("/user")  .contentType(MediaType.APPLICATION_JSON).content(requestBody)  .accept(MediaType.APPLICATION_JSON)) //執行請求  .andExpect(content().contentType(MediaType.APPLICATION_JSON)) //驗證響應contentType  .andExpect(jsonPath("$.id").value(1)); //使用Json path驗證JSON 請參考http://goessner.net/articles/JsonPath/  String errorBody = "{id:1, name:zhang}";  MvcResult result = mockMvc.perform(post("/user")  .contentType(MediaType.APPLICATION_JSON).content(errorBody)  .accept(MediaType.APPLICATION_JSON)) //執行請求  .andExpect(status().isBadRequest()) //400錯誤請求  .andReturn();  Assert.assertTrue(HttpMessageNotReadableException.class.isAssignableFrom(result.getResolvedException().getClass()));//錯誤的請求內容體
復制代碼

?

6.異步測試

復制代碼
  //Callable  MvcResult result = mockMvc.perform(get("/user/async1?id=1&name=zhang")) //執行請求  .andExpect(request().asyncStarted())  .andExpect(request().asyncResult(CoreMatchers.instanceOf(User.class))) //默認會等10秒超時  .andReturn();  mockMvc.perform(asyncDispatch(result))  .andExpect(status().isOk())  .andExpect(content().contentType(MediaType.APPLICATION_JSON))  .andExpect(jsonPath("$.id").value(1));  
復制代碼

?

7.全局配置

復制代碼
mockMvc = webAppContextSetup(wac)  .defaultRequest(get("/user/1").requestAttr("default", true)) //默認請求 如果其是Mergeable類型的,會自動合并的哦mockMvc.perform中的RequestBuilder  .alwaysDo(print())  //默認每次執行請求后都做的動作  .alwaysExpect(request().attribute("default", true)) //默認每次執行后進行驗證的斷言  .build();  mockMvc.perform(get("/user/1"))  .andExpect(model().attributeExists("user"));  
復制代碼

?

轉載于:https://www.cnblogs.com/williamjie/p/9145165.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452398.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452398.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452398.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

自頂向下和自底向上測試的優缺點

自頂向下測試方法的主要優點是不需要測試驅動程序&#xff0c;能夠在測試階段的早期實現并驗證系統的主要功能&#xff0c;而且能在早期發現上層模塊的接口錯誤。 自頂向下測試方法的主要缺點是需要存根程序&#xff0c;可能遇到與此相聯系的測試困難&#xff0c;低層關鍵模塊中…

C++ class中的靜態(static)成員

C class中的靜態(static)成員 &#xff08;1&#xff09; 靜態數據成員 ①一般地靜態數據成員在該類定義之外被初始化&#xff0c;如同一個成員函數被定義在類定義之外一樣。在這種定義中的靜態成員的名字必須被其類名限定修飾&#xff0c;例如下面是_interestRate的初始…

用計算機彈可惜不是你,可惜不是你 還是幸虧不是你

一、 你沒有再挽留 我也沒有再回頭 就這樣 無風無雨也無晴 無疾而終二、 是我孤陋寡聞不知你心有人三、 如果作業有葬禮,全體學生定當盛裝出席.四、 縱使我有千般好 你也看不到 因為你沒有一雙愛我的眼睛五、 原來暫時共你沒緣分 來年先會變得更合襯六、 真的別回頭 你有未來 你…

PHP 完整實戰23種設計模式

PHP實戰創建型模式 單例模式 工廠模式 抽象工廠模式 原型模式 建造者模式 PHP實戰結構型模式 橋接模式 享元模式 外觀模式 適配器模式 裝飾器模式 組合模式 代理模式 過濾器模式 PHP實戰行為型模式 模板模式 策略模式 狀態模式 觀察者模式 責任鏈模式 訪問者模…

Diango博客--16.穩定易用的 Django 分頁庫,完善分頁功能(二)

文章目錄0.思路引導1.分頁效果概述2.分頁思路3.Django 第三方拓展&#xff1a;django-pure-pagination4.自定義模板0.思路引導 1&#xff09;在前面我們通過 Django Pagination 實現簡單分頁 中&#xff0c;我們實現了一個簡單的分頁導航。但效果有點差強人意&#xff0c;我們…

回歸測試

在集成測試過程中&#xff0c;每當一個新模塊結合進來時&#xff0c;程序就發生了變化&#xff1a;建立了新的數據流路徑&#xff0c;可能出現了新的I/O操作&#xff0c;激活了新的控制邏輯。在集成測試的范疇中&#xff0c;回歸測試是指重新執行已經做過的測試的某個子集&…

不同的寫法 其中 1 2 (試了下 沒有效果 ,先記載這里把)

轉載于:https://www.cnblogs.com/kaibindirver/p/9145455.html

美國西北大學 計算機工程專業排名,[轉載]美國西北大學計算機工程研究生最新專業排名...

對于打算去美國西北大學讀研究生的學生來講&#xff0c;美國西北大學研究生申請要求及美國西北大學研究生專業介紹是學生最關心的問題。本文香港介紹美國西北大學研究生申請要求及美國西北大學研究生的專業介紹&#xff0c;幫助更多的學生更好的了解美國西北大學。2016年西北大…

析構函數virtual與非virtual區別

作為通常的原則&#xff0c;如果一個類定義了虛函數&#xff0c;那么它的析構函數就應當是virtual的。因為定義了虛函數則隱含著&#xff1a;這個類會被繼承&#xff0c;并且會通過基類的指針指向子類對象&#xff0c;從而得到多態性。 這個類可能會被繼承&#xff0c;并且會…

Python:字典列表字符串方法測試

測試的一些Python中的關于字典、列表、字符串的使用方法&#xff0c;放在這里備查。整個測試代碼和說明如下&#xff1a; # -*- coding: utf-8 -*- """Python:函數中全是指針傳遞&#xff0c;而任何變量都是給予一個指針指向一個內存空間"""impo…

什么是確認測試

確認測試也稱為驗收測試&#xff0c;它的目標是驗證軟件的有效性。 通常&#xff0c;驗證指的是保證軟件正確地實現了某個特定要求的一系列活動&#xff1b;確認指的是為了保證軟件確實滿足了用戶需求而進行的一系列活動。 軟件有效性的一個簡單定義是&#xff1a;如果軟件的功…

Diango博客--17.統計各個分類和標簽下的文章數

文章目錄0.思路引導1.Model 回顧2.數據庫數據聚合3.使用 Annotate4.在模板中引用新增的屬性0.思路引導 在我們的博客側邊欄有分類列表和標簽列表&#xff0c;顯示博客已有的全部文章分類。現在想在分類名和標簽名后顯示該分類或者標簽下有多少篇文章&#xff0c;該怎么做呢&am…

HTTP協議中request報文請求方法和狀態響應碼

一個HTTP請求報文由4部分組成&#xff1a; 請求行&#xff08;request line&#xff09;請求頭部&#xff08;header&#xff09;空行請求數據下圖給出了請求報文的一般格式&#xff1a; 請求行中包括了請求方法&#xff0c;常見的請求方法有&#xff1a; GET&#xff1a;從服務…

計算機無法安裝64位操作系統,為什么我的win7旗艦版service Pack 1 64位操作系統 無法安裝(KB2670838) 這個更新...

您好&#xff01;我了解到您遇到關于這邊的問題請問無法安裝是否出現了什么錯誤代碼提示呢&#xff1f;請參考以下的步驟解決按WindowsR打開cmd里使用下面的命令關閉相關的一些服務&#xff1a;net stop wuauservnet stop cryptSvcnet stop bitsnet stop msiserver完成后&#…

bmon:一個強大的網絡帶寬監視和調試工具

bmon 是類 Unix 系統中一個基于文本&#xff0c;簡單但非常強大的 網絡監視和調試工具&#xff0c;它能抓取網絡相關統計信息并把它們以用戶友好的格式展現出來。它是一個可靠高效的帶寬監視和網速估測工具。 它能使用各種輸入模塊讀取輸入&#xff0c;并以各種輸出模式顯示輸出…

函數的調用規則(__cdecl,__stdcall,__fastcall,__pascal)

關于函數的調用規則&#xff08;調用約定&#xff09;&#xff0c;大多數時候是不需要了解的&#xff0c;但是如果需要跨語言的編程&#xff0c;比如VC寫的dll要delphi調用&#xff0c;則需要了解。 microsoft的vc默認的是__cdecl方式&#xff0c;而windows API則是__stdcall&a…

Linux 下的/usr/bin /usr/sbin /usr/local/bin /usr/local/sbin區別

1、/bin 是所有用戶都可以訪問并執行的可執行程序。包括超級用戶及一般用戶。 供所有用戶&#xff08;包括root用戶和一般用戶&#xff09;使用的基本命令&#xff0c;主要有cat,chmod,date,cp,bash等等常用的命令。 2、/usr/bin&#xff1a;系統預裝的可執行程序&#xff0c;…

alpha測試和betal測試

如果一個軟件是為許多客戶開發的&#xff08;例如&#xff0c;向大眾公開出售的盒裝軟件產品&#xff09;&#xff0c;那么絕大多數軟件開發商都使用被稱為Alpha測試和Beta測試的過程&#xff0c;來發現那些看起來只有最終用戶才能發現的錯誤。 Alpha測試由用戶在開發者的場所進…

計算機d盤無法格式化,四種方法解決D盤無法格式化問題

不少朋友系統出現故障&#xff0c;幾乎都是選擇重裝系統的方法來解決問題。系統重裝后&#xff0c;不少朋友覺得D盤沒有什么重要的東西&#xff0c;就想將其格式化&#xff0c;可是系統出現windows無法格式該驅動器的提示&#xff0c;這是怎么回事呢&#xff1f;D盤無法格式化要…

sqlserver視圖

作用 ①簡化了操作&#xff0c;把經常使用的數據定義為視圖。 ②安全性&#xff0c;用戶只能查詢和修改能看到的數據。 ③邏輯上的獨立性&#xff0c;屏蔽了真實表的結構帶來的影響。 對視圖的修改&#xff1a;單表視圖一般用于查詢和修改&#xff0c;會改變基本表的數據&#…