Spring?MVC中的Controller進(jìn)行單元測(cè)試的實(shí)現(xiàn)
對(duì)Controller進(jìn)行單元測(cè)試是Spring框架原生就支持的能力,它可以模擬HTTP客戶端發(fā)起對(duì)服務(wù)地址的請(qǐng)求,可以不用借助于諸如Postman這樣的外部工具就能完成對(duì)接口的測(cè)試。
具體來(lái)講,是由Spring框架中的spring-test模塊提供的實(shí)現(xiàn),詳見MockMvc。
如下將詳細(xì)闡述如何使用MockMvc測(cè)試框架實(shí)現(xiàn)對(duì)“Spring Controller”進(jìn)行單元測(cè)試,基于Spring Boot開發(fā)框架進(jìn)行驗(yàn)證。
添加測(cè)試框架依賴:
<!-- Spring框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
!<-- Spring測(cè)試框架 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 文件操作工具 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
導(dǎo)入靜態(tài)工具方法
為了便于在編寫測(cè)試用例時(shí)直接調(diào)用測(cè)試框架自帶的靜態(tài)方法,首先需要導(dǎo)入這些靜態(tài)工具方法。
需要導(dǎo)入的靜態(tài)方法如下:
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; import static org.springframework.test.web.servlet.setup.SharedHttpSessionConfigurer.*;
初始化MockMvc
初始化MockMvc有2種方式:
方式1:明確指定需要測(cè)試的“Controller”類進(jìn)行配置
方式2:基于Spring容器進(jìn)行配置,包含了Spring MVC環(huán)境和所有“Controller”類,通常使用這種方式。
@SpringBootTest
public class TestControllerTest {
MockMvc mockMvc;
// 初始化MockMvc
@BeforeEach
void setUp(WebApplicationContext wac) {
// 方式1:明確指定需要測(cè)試的“Controller”類
this.mockMvc = MockMvcBuilders.standaloneSetup(new TestController()).build();
// 方式2:基于Spring容器進(jìn)行配置,包含了Spring MVC環(huán)境和所有“Controller”類。
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}
}
另外,還可以對(duì)MockMvc進(jìn)行全局配置。
// 全局配置MockMvc
this.mockMvc = MockMvcBuilders.webAppContextSetup(wac)
.defaultRequest(get("/").accept(MediaType.APPLICATION_JSON)) // 默認(rèn)請(qǐng)求路徑
.apply(sharedHttpSession()) // 配置session
.alwaysExpect(status().isOk()) // 預(yù)期響應(yīng)狀態(tài)碼
.alwaysExpect(content().contentType("application/json;charset=UTF-8")) // 預(yù)期內(nèi)容類型
.build();
執(zhí)行測(cè)試
MockMvc支持對(duì)常見的HTTP方法,如:GET,POST,PUT,DELETE等,甚至還支持文件上傳請(qǐng)求。
測(cè)試GET接口
// 訪問(wèn)GET接口:不帶參數(shù)
@Test
public void testSimpleGet() throws Exception {
MvcResult result = this.mockMvc.perform(get("/test/simple/get")
.accept(MediaType.APPLICATION_JSON)) // 接受JSON格式響應(yīng)消息
.andReturn(); // 獲取返回結(jié)果
Assertions.assertEquals("OK", result.getResponse().getContentAsString());
}
// 訪問(wèn)GET接口:帶URL參數(shù)
@Test
public void testParamGet() throws Exception {
int id = 10;
// 方式1:在URI模板中指定參數(shù)
//MvcResult result = this.mockMvc.perform(get("/test/param/get?id={id}", id).accept(MediaType.APPLICATION_JSON)).andReturn();
// 方式2:通過(guò)param()方法指定參數(shù)
//MvcResult result = this.mockMvc.perform(get("/test/param/get").param("id", String.valueOf(id)).accept(MediaType.APPLICATION_JSON)).andReturn();
// 方式3:通過(guò)queryParam()方法指定參數(shù)
MvcResult result = this.mockMvc.perform(get("/test/param/get").queryParam("id", String.valueOf(id)).accept(MediaType.APPLICATION_JSON)).andReturn();
Assertions.assertEquals("OK: " + id, result.getResponse().getContentAsString());
}
測(cè)試POST接口
// 傳遞表單參數(shù)
@Test
public void testSimplePost() throws Exception {
int id = 10;
// 調(diào)用param()方法傳遞參數(shù)
MvcResult result = this.mockMvc.perform(post("/test/simple/post")
.param("id", String.valueOf(id))
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.accept(MediaType.APPLICATION_JSON))
.andReturn();
Assertions.assertEquals("{\"id\":10}", result.getResponse().getContentAsString());
}
// 傳遞JSON參數(shù)
@Test
public void testSimplePostJson() throws Exception {
// 調(diào)用content()方法傳遞json字符串參數(shù)
Subject subject = new Subject();
subject.setId(10);
String content = JSON.toJSONString(subject);
MvcResult result = this.mockMvc.perform(post("/test/simple/post/json")
.content(content)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andReturn();
Assertions.assertEquals("{\"id\":10}", result.getResponse().getContentAsString());
}
測(cè)試文件上傳
@Test
public void testFileUploadSingle() throws Exception {
File file = new File("C:\\Users\\xxx\\Downloads\\test.jpg");
String fileName = FilenameUtils.getName(file.getName());
byte[] bytes = FileUtils.readFileToByteArray(file);
MockMultipartFile mockMultipartFile = new MockMultipartFile("file", fileName, MediaType.MULTIPART_FORM_DATA_VALUE, bytes);
this.mockMvc.perform(multipart("/test/upload/single").file(mockMultipartFile))
.andExpect(status().isOk())
.andExpect(content().string("OK"))
.andDo(print());
}
定義預(yù)期結(jié)果
斷言響應(yīng)結(jié)果時(shí),有2種方式:
1.使用JUnit提供的Assert斷言工具判斷返回結(jié)果,這是一種非常普遍和常見的方式
2.在MockMvc框架中可以通過(guò)andExpect()方法定義一個(gè)或多個(gè)預(yù)期結(jié)果,當(dāng)其中一個(gè)期望結(jié)果斷言失敗時(shí),就不會(huì)斷言其他期望值了
// 使用Junit斷言工具判斷返回結(jié)果是否符合預(yù)期
@Test
public void testAssertResult() throws Exception {
MvcResult result = this.mockMvc.perform(get("/test/simple/get").accept(MediaType.APPLICATION_JSON)).andDo(print()).andReturn();
Assert.assertEquals("OK", result.getResponse().getContentAsString());
}
// 在MockMvc框架中定義預(yù)期結(jié)果
@Test
public void testExpectations() throws Exception {
this.mockMvc.perform(get("/test/simple/get").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()) // 預(yù)期響應(yīng)狀態(tài)碼為200
.andExpect(content().string("OK")) // 預(yù)期返回值為字符串“OK”
.andDo(print());
}
相比于使用Junit的斷言工具判斷返回結(jié)果,在MockMvc框架中直接定義預(yù)期結(jié)果進(jìn)行斷言檢查更加簡(jiǎn)潔。
寫在最后
使用Spring提供的測(cè)試框架MockMvc可以非常方便地實(shí)現(xiàn)對(duì)HTTP服務(wù)接口進(jìn)行單元測(cè)試,不要把基礎(chǔ)的功能驗(yàn)證工作都交給測(cè)試童鞋,應(yīng)該通過(guò)單元測(cè)試來(lái)保證代碼迭代的穩(wěn)定性。
到此這篇關(guān)于Spring MVC中的Controller進(jìn)行單元測(cè)試的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Spring MVC Controller單元測(cè)試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
3行代碼快速實(shí)現(xiàn)Spring Boot Oauth2服務(wù)功能
oauthserver是一個(gè)基于Spring Boot Oauth2的完整的獨(dú)立的Oauth服務(wù)器。僅僅需要?jiǎng)?chuàng)建相關(guān)數(shù)據(jù)表,修改數(shù)據(jù)庫(kù)的連接信息,你就可以得到一個(gè)Oauth服務(wù)器。這篇文章給大家介紹3行代碼快速實(shí)現(xiàn)Spring Boot Oauth2服務(wù)功能,需要的朋友參考下吧2018-04-04
Java?Chassis3負(fù)載均衡選擇器技術(shù)解密
這篇文章主要為大家介紹了Java?Chassis3負(fù)載均衡選擇器技術(shù)解密,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2024-01-01
如何兩步解決maven依賴導(dǎo)入失敗的問(wèn)題
這篇文章主要介紹了如何兩步解決maven依賴導(dǎo)入失敗的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
JAVA8 stream中三個(gè)參數(shù)的reduce方法對(duì)List進(jìn)行分組統(tǒng)計(jì)操作
這篇文章主要介紹了JAVA8 stream中三個(gè)參數(shù)的reduce方法對(duì)List進(jìn)行分組統(tǒng)計(jì)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08

