詳解Spring MVC如何測(cè)試Controller(使用springmvc mock測(cè)試)
在springmvc中一般的測(cè)試用例都是測(cè)試service層,今天我來(lái)演示下如何使用springmvc mock直接測(cè)試controller層代碼。
1.什么是mock測(cè)試?
mock測(cè)試就是在測(cè)試過(guò)程中,對(duì)于某些不容易構(gòu)造或者不容易獲取的對(duì)象,用一個(gè)虛擬的對(duì)象來(lái)創(chuàng)建以便測(cè)試的測(cè)試方法。
2.為什么要使用mock測(cè)試?
使用Mock O bject進(jìn)行測(cè)試,主要是用來(lái)模擬那些在應(yīng)用中不容易構(gòu)造(如HttpServletRequest必須在Servlet容器中才能構(gòu)造出來(lái))或者比較復(fù)雜的對(duì)象(如JDBC中的ResultSet對(duì)象)從而使測(cè)試順利進(jìn)行的工具。
3.常用注解
RunWith(SpringJUnit4ClassRunner.class): 表示使用Spring Test組件進(jìn)行單元測(cè)試;
WebAppConfiguratio: 使用這個(gè)annotation會(huì)在跑單元測(cè)試的時(shí)候真實(shí)的啟一個(gè)web服務(wù),然后開(kāi)始調(diào)用Controller的Rest API,待單元測(cè)試跑完之后再將web服務(wù)停掉;
ContextConfiguration: 指定Bean的配置文件信息,可以有多種方式,這個(gè)例子使用的是文件路徑形式,如果有多個(gè)配置文件,可以將括號(hào)中的信息配置為一個(gè)字符串?dāng)?shù)組來(lái)表示;
4.安裝測(cè)試環(huán)境
spring mvc測(cè)試框架提供了兩種方式,獨(dú)立安裝和集成Web環(huán)境測(cè)試(此種方式并不會(huì)集成真正的web環(huán)境,而是通過(guò)相應(yīng)的Mock API進(jìn)行模擬測(cè)試,無(wú)須啟動(dòng)服務(wù)器)。
獨(dú)立安裝測(cè)試方式
MockMvcBuilders.standaloneSetup(Object... controllers):通過(guò)參數(shù)指定一組控制器,這樣就不需要從上下文獲取了;
主要是兩個(gè)步驟:
(1)首先自己創(chuàng)建相應(yīng)的控制器,注入相應(yīng)的依賴
(2)通過(guò)MockMvcBuilders.standaloneSetup模擬一個(gè)Mvc測(cè)試環(huán)境,通過(guò)build得到一個(gè)MockMvc
代碼如下:
package com.xfs.test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xfs.web.controller.APIController;
/**
* 獨(dú)立安裝測(cè)試方式 springmvc mock測(cè)試
*
* @author admin
*
* 2017年11月23日 上午10:39:49
*/
public class TestApiOne {
private MockMvc mockMvc;
@Before
public void setUp() {
APIController apiController = new APIController();
mockMvc = MockMvcBuilders.standaloneSetup(apiController).build();
}
@Test
public void testGetSequence() {
try {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/api/getSequence"))
.andExpect(MockMvcResultMatchers.status().is(200))
.andDo(MockMvcResultHandlers.print())
.andReturn();
int status = mvcResult.getResponse().getStatus();
System.out.println("請(qǐng)求狀態(tài)碼:" + status);
String result = mvcResult.getResponse().getContentAsString();
System.out.println("接口返回結(jié)果:" + result);
JSONObject resultObj = JSON.parseObject(result);
// 判斷接口返回json中success字段是否為true
Assert.assertTrue(resultObj.getBooleanValue("success"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
請(qǐng)求結(jié)果如下:



集成Web環(huán)境方式
MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,將會(huì)從該上下文獲取相應(yīng)的控制器并得到相應(yīng)的MockMvc;
主要是三個(gè)步驟:
(1)@WebAppConfiguration:測(cè)試環(huán)境使用,用來(lái)表示測(cè)試環(huán)境使用的ApplicationContext將是WebApplicationContext類型的;value指定web應(yīng)用的根
(2)通過(guò)@Autowired WebApplicationContext wac:注入web環(huán)境的ApplicationContext容器
(3)然后通過(guò)MockMvcBuilders.webAppContextSetup(wac).build()創(chuàng)建一個(gè)MockMvc進(jìn)行測(cè)試
代碼如下:
package com.xfs.test;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpSession;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
/**
* 集成Web環(huán)境方式 springmvc mock測(cè)試
*
* @author admin
*
* 2017年11月23日 上午11:12:43
*/
@RunWith(JUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(locations = { "classpath*:spring/*.xml" })
public class TestApiTwo extends AbstractJUnit4SpringContextTests {
@Autowired
public WebApplicationContext wac;
public MockMvc mockMvc;
public MockHttpSession session;
@Before
public void before() throws Exception {
mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
@Test
public void testGetSequence() {
try {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/api/getSequence"))
.andExpect(MockMvcResultMatchers.status().is(200))
.andDo(MockMvcResultHandlers.print())
.andReturn();
int status = mvcResult.getResponse().getStatus();
System.out.println("請(qǐng)求狀態(tài)碼:" + status);
String result = mvcResult.getResponse().getContentAsString();
System.out.println("接口返回結(jié)果:" + result);
JSONObject resultObj = JSON.parseObject(result);
// 判斷接口返回json中success字段是否為true
Assert.assertTrue(resultObj.getBooleanValue("success"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
運(yùn)行結(jié)果和上面獨(dú)立測(cè)試時(shí)候一樣。
總結(jié):
整個(gè)過(guò)程:
1、mockMvc.perform執(zhí)行一個(gè)請(qǐng)求;
2、MockMvcRequestBuilders.get("/user/1")構(gòu)造一個(gè)請(qǐng)求
3、ResultActions.andExpect添加執(zhí)行完成后的斷言
4、ResultActions.andDo添加一個(gè)結(jié)果處理器,表示要對(duì)結(jié)果做點(diǎn)什么事情,比如此處使用MockMvcResultHandlers.print()輸出整個(gè)響應(yīng)結(jié)果信息。
5、ResultActions.andReturn表示執(zhí)行完成后返回相應(yīng)的結(jié)果。
整個(gè)測(cè)試過(guò)程非常有規(guī)律:
1、準(zhǔn)備測(cè)試環(huán)境
2、通過(guò)MockMvc執(zhí)行請(qǐng)求
3、添加驗(yàn)證斷言
4、添加結(jié)果處理器
5、得到MvcResult進(jìn)行自定義斷言/進(jìn)行下一步的異步請(qǐng)求
6、卸載測(cè)試環(huán)境
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)查找文本內(nèi)容替換功能示例
文本替換幾乎是所有文本編輯器都支持的功能,但是要限制在編輯其中才可以執(zhí)行該功能。本實(shí)例實(shí)現(xiàn)了制定文本文件的內(nèi)容替換,并且不需要再編輯其中打開(kāi)文本文件2014-02-02
Java中使用Apache POI讀取word文件簡(jiǎn)單示例
這篇文章主要介紹了Java中使用Apache POI讀取word文件簡(jiǎn)單示例,本文著重介紹了一些必要條件,然后給出一個(gè)簡(jiǎn)單讀取示例,需要的朋友可以參考下2015-06-06
Java實(shí)現(xiàn)十秒向MySQL插入百萬(wàn)條數(shù)據(jù)
這篇文章主要為大家詳細(xì)介紹了Java如何實(shí)現(xiàn)十秒向MySQL插入百萬(wàn)條數(shù)據(jù),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定借鑒價(jià)值,需要的可以參考一下2022-11-11
Java并發(fā)實(shí)例之CyclicBarrier的使用
這篇文章主要介紹了Java并發(fā)實(shí)例之CyclicBarrier的使用,涉及CyclicBarrier的介紹,以及相關(guān)的并發(fā)實(shí)例,具有一定參考價(jià)值,需要的朋友可以了解下。2017-11-11
IntelliJ IDEA中顯示和關(guān)閉工具欄與目錄欄的方法
今天小編就為大家分享一篇關(guān)于IntelliJ IDEA中顯示和關(guān)閉工具欄與目錄欄的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2018-10-10
Java使用Optional實(shí)現(xiàn)優(yōu)雅避免空指針異常
空指針異常(NullPointerException)可以說(shuō)是Java程序員最容易遇到的問(wèn)題了。為了解決這個(gè)問(wèn)題,Java?8?版本中推出了?Optional?類,本文就來(lái)講講如何使用Optional實(shí)現(xiàn)優(yōu)雅避免空指針異常吧2023-03-03
MyBatis實(shí)現(xiàn)物理分頁(yè)的實(shí)例
這篇文章主要介紹了MyBatis實(shí)現(xiàn)物理分頁(yè)的實(shí)例,MyBatis使用RowBounds實(shí)現(xiàn)的分頁(yè)是邏輯分頁(yè),有興趣的可以了解一下。2017-01-01
Spring Boot 配置隨機(jī)數(shù)的技巧代碼詳解
這篇文章主要介紹了Spring Boot 配置隨機(jī)數(shù)技巧,spring boot 支持在系統(tǒng)加載的時(shí)候配置隨機(jī)數(shù),具體實(shí)例代碼大家參考下本文2018-05-05

