<h1>日常啰嗦</h1>
承接前一篇文章《Spring+SpringMVC+MyBatis+easyUI整合優(yōu)化篇(四)單元測(cè)試實(shí)例》,已經(jīng)講解了dao層和service層的單元測(cè)試辽话,還有控制器這層也不能漏掉,因此本篇會(huì)講一下MockMvc冰更,及controller控制層的單元測(cè)試尚辑,相關(guān)代碼已上傳,可自行下載呻粹。
我的github地址
<h1>為什么使用MockMvc?</h1>
可能我們?cè)跍y(cè)試控制層的代碼都是啟動(dòng)服務(wù)器苏研,在瀏覽器中輸入U(xiǎn)RL等浊,然后開始測(cè)試是否達(dá)到預(yù)期效果,發(fā)生錯(cuò)誤的話摹蘑,修改相關(guān)代碼并重啟服務(wù)器再次進(jìn)行測(cè)試筹燕。分析一下這個(gè)過程,啟動(dòng)服務(wù)器-->打開瀏覽器-->輸入U(xiǎn)RL-->等待返回結(jié)果-->修復(fù)bug-->重啟服務(wù)器.....循環(huán)。
其中的缺點(diǎn)也挺明顯的撒踪,在瀏覽器輸入U(xiǎn)RL的地址过咬,如果是GET請(qǐng)求還好,POST請(qǐng)求或者DELETE請(qǐng)求怎么辦制妄?只能借助其他工具掸绞,通過命令行編寫curl語(yǔ)句,或者借助谷歌瀏覽器的postman插件忍捡,亦或者自己在代碼中通過編寫相應(yīng)httpClient方法來實(shí)現(xiàn)測(cè)試集漾,但是這幾種方法都較為麻煩切黔,而且測(cè)試用例并不能較好的保存砸脊。再說一個(gè)缺點(diǎn),代碼修改后纬霞,往往需要再次重啟服務(wù)器凌埂,等待啟動(dòng)完畢才能接下來的測(cè)試過程。
如果tomcat服務(wù)器啟動(dòng)速度較慢诗芜,這將是一件非常痛苦的事情瞳抓,測(cè)試驗(yàn)證也不方便,且依賴網(wǎng)絡(luò)環(huán)境伏恐,這些原因?qū)е聹y(cè)試起來很麻煩孩哑,而為了可以方便對(duì)Controller進(jìn)行測(cè)試,且很好的保存和循環(huán)使用測(cè)試用例翠桦,則可以通過單元測(cè)試來解決横蜒,通過前面一篇文章,大家對(duì)于單元測(cè)試的便利性有了認(rèn)識(shí)和體會(huì)销凑,接下來通過引入MockMVC進(jìn)行控制層的單元測(cè)試丛晌。
MockMvc實(shí)現(xiàn)了對(duì)Http請(qǐng)求的模擬,能夠直接使用網(wǎng)絡(luò)的形式斗幼,轉(zhuǎn)換到Controller的調(diào)用澎蛛,這樣可以使得測(cè)試速度快、不依賴網(wǎng)絡(luò)環(huán)境蜕窿,而且提供了一套驗(yàn)證的工具谋逻,這樣可以使得請(qǐng)求的驗(yàn)證統(tǒng)一而且很方便。
<h1>MockMvc單元測(cè)試實(shí)例</h1>
MockMvc測(cè)試過程:
1桐经、創(chuàng)建請(qǐng)求
2斤贰、設(shè)置參數(shù)(這一步其實(shí)可以設(shè)置很多參數(shù),MockMvc提供了豐富的方法次询,但是本例中只是簡(jiǎn)單的參數(shù)設(shè)置荧恍,因?yàn)榉椒ǘ驾^簡(jiǎn)單,并沒有復(fù)雜的調(diào)用)
3、mockMvc調(diào)用perform送巡,調(diào)用controller的業(yè)務(wù)處理邏輯
4摹菠、perform返回ResultActions,返回操作結(jié)果骗爆,通過ResultActions次氨,提供了統(tǒng)一的驗(yàn)證方式。
測(cè)試代碼在test包中摘投,也已經(jīng)傳到github上煮寡,可以下載到本地運(yùn)行測(cè)試。
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({"classpath*:/applicationContext.xml", "classpath*:/spring-mvc.xml", "classpath*:/mybatis-config.xml"})
public class BookControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = webAppContextSetup(this.wac).build();
}
@Test
public void testList() throws Exception {
//創(chuàng)建書籍列表的請(qǐng)求
//請(qǐng)求方式為get
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.get("/book/listAll.do");
//此請(qǐng)求并不需要添加請(qǐng)求參數(shù) mockMvc.perform(mockHttpServletRequestBuilder).andExpect(status().isOk())
.andDo(print());
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({"classpath*:/applicationContext.xml", "classpath*:/spring-mvc.xml", "classpath*:/mybatis-config.xml"})
@TransactionConfiguration(defaultRollback = false)
@Transactional
public class StoreControllerTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = webAppContextSetup(this.wac).build();
}
@Test
public void testSave() throws Exception {
//創(chuàng)建書架創(chuàng)建的請(qǐng)求
//請(qǐng)求方式為post
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.post("/store/save.do");
//添加編號(hào)為MockMvc的書架
mockHttpServletRequestBuilder.param("number", "MockMvc");
//書架為兩層
mockHttpServletRequestBuilder.param("level", "2");
mockMvc.perform(mockHttpServletRequestBuilder).andExpect(status().isOk())
.andDo(print());
}
@Test
public void testList() throws Exception {
//創(chuàng)建書架創(chuàng)建的請(qǐng)求
//請(qǐng)求方式為post
MockHttpServletRequestBuilder mockHttpServletRequestBuilder = MockMvcRequestBuilders.post("/store/list.do");
//有些參數(shù)我注釋掉了犀呼,你可以自行添加相關(guān)參數(shù)幸撕,得到不同的測(cè)試結(jié)果
//status為0的記錄
//mockHttpServletRequestBuilder.param("status", "0");
//書架編號(hào)為dd的記錄
//mockHttpServletRequestBuilder.param("number", "dd");
//第一頁(yè)
mockHttpServletRequestBuilder.param("page", "1");
//每頁(yè)10條記錄
mockHttpServletRequestBuilder.param("rows", "10");
mockMvc.perform(mockHttpServletRequestBuilder).andExpect(status().isOk())
.andDo(print());
//控制臺(tái)會(huì)打印如下結(jié)果:
//MockHttpServletResponse:
//Status = 200 即為后端成功相應(yīng)
//返回?cái)?shù)據(jù)
}
}
<h1>總結(jié)</h1>
如果你還是習(xí)慣于啟動(dòng)tomcat服務(wù)器,然后在瀏覽器中輸入地址測(cè)試的話外臂,也未嘗不可坐儿,方法在上面,已經(jīng)寫好了宋光,使不使用還是要看個(gè)人習(xí)慣的貌矿。
以上的測(cè)試都是針對(duì)本項(xiàng)目的簡(jiǎn)單測(cè)試,應(yīng)該都不是很復(fù)雜罪佳,很容易上手的逛漫,后面如果有復(fù)雜的測(cè)試的話,再進(jìn)行深入的講解赘艳,想要深入了解SpringMVC的MockMvc測(cè)試的話可以自行搜索相關(guān)教程酌毡。