SpringBoot通过MockMvc进行单元测试的正确打开方式
第一步:毋庸置疑给它找个包用用
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
第二步:自己写一个接口,可以根据自己的喜好随意书写(想怎么写就怎么写,举个栗子)
/**
* @param name 名称
* @return
* @url /tdsscheckmaster/hello/{name} 接口路径
* ver_tdsscheckmaster_hello 这个东东是权限
*/
@GetMapping("/hello/{name}")
@PreAuthorize("@pms.hasPermission('ver_tdsscheckmaster_hello')")
public ResponseBody getHello(@PathVariable("name") String name) {
return ResponseBody.ok("hello ".concat(name).concat("!"));
}
到此为止 大伙已经完成了最重要的一步了 接下来开始玩Java特性(当然各位大佬玩的比我熟,直接上代码)
第三步:写一个爹类
父类的创建位置:大概在这里(父类名称你们自己随便取,别太长毕竟要继承的少写一点是一点)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KlQ73wpf-1608515657042)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20201214151653807.png)]
package com.cloud.msrp.verification.controller;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public class BaseControllerTest {
protected MockMvc mockMvc;
@Autowired
private WebApplicationContext webApplicationContext;
@Before
public void setup() {
// 实例化方式一
//mockMvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
// 实例化方式二
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
第四步:写个子类(继承一下,继承的特性就不用多说了。反正就是偷懒少写代码)
package com.cloud.msrp.verification.controller;
import com.alibaba.fastjson.JSON;
import org.junit.Test;
import org.springframework.security.test.context.support.WithMockUser;
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 javax.ws.rs.core.MediaType;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class TDssCheckMasterControllerTest extends BaseControllerTest {
/**
* 这个是Get的案例
* @throws Exception
*/
@Test
//这个东东是权限
@WithMockUser(authorities = {"ver_tdsscheckmaster_hello"})
public void helloTest() throws Exception {
Map map = new HashMap<>();
// MockMvcRequestBuilders.post()
//这个是接口路径
MvcResult mvcResult= mockMvc.perform(MockMvcRequestBuilders.get("/tdsscheckmaster/hello/Tom"))
//这个是判断是否接口走通
.andExpect(MockMvcResultMatchers.status().isOk())
//这个是匹配接口返回数据是否一致(类似于.equals())
.andExpect(MockMvcResultMatchers.content().string("{\"code\":0,\"msg\":null,\"data\":\"hello Tom!\"}"));
int status=mvcResult.getResponse().getStatus(); //得到返回代码
String content=mvcResult.getResponse().getContentAsString(); //得到返回结果
Assert.assertEquals(200,status); //断言,判断返回代码是否正确
Assert.assertEquals("hello lvgang",content); //断言,判断返回的值是否正确
}
/**
* 这个是Post的案例
* @throws Exception
*/
@Test
public void dataShow() throws Exception {
Map<String,Object> map = new HashMap<>();
String id = "1306856715601334273";
map.put("id",id);
String str = JSON.toJSONString(map);
//因为是post要注意格式问题
mockMvc.perform(MockMvcRequestBuilders.post("/tdsscheckmaster/auditInit").contentType(MediaType.APPLICATION_JSON)
.content(str))
.andExpect(MockMvcResultMatchers.status().isOk())
//这个是将返回的数据在控制台打印
.andDo(MockMvcResultHandlers.print());
}
}
到这里单元测试就差不多完成了,当然还有很多种用法和写法省的各位兄弟们一个个去百度 我这里都给兄弟们百度过来了
以下部分代码来着https://my.oschina.net/sdlvzg/blog/1594821
/**
* 1、mockMvc.perform执行一个请求。
* 2、MockMvcRequestBuilders.get("XXX")构造一个请求。
* 3、ResultActions.param添加请求传值
* 4、ResultActions.accept(MediaType.TEXT_HTML_VALUE))设置返回类型
* 5、ResultActions.andExpect添加执行完成后的断言。
* 6、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情
* 比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
* 7、ResultActions.andReturn表示执行完成后返回相应的结果。
*/
这里再举一个栗子吧(根据上面的Get方法换了一种写法)
/**
* 这个是Get的案例
* @throws Exception
*/
@Test
//这个东东是权限
@WithMockUser(authorities = {"ver_tdsscheckmaster_hello"})
public void helloTest() throws Exception {
Map map = new HashMap<>();
//这个是接口路径
MvcResult mvcResult=mockMvc.perform(MockMvcRequestBuilders.get("/tdsscheckmaster/hello/Tom"))
//.param("name","Tom")
//.accept(MediaType.TEXT_HTML_VALUE))
.andDo(MockMvcResultHandlers.print())
.andReturn();
int status=mvcResult.getResponse().getStatus(); //得到返回代码
String content=mvcResult.getResponse().getContentAsString(); //得到返回结果
Assert.assertEquals(200,status); //断言,判断返回代码是否正确
Assert.assertEquals("{\"code\":0,\"msg\":null,\"data\":\"hello Tom!\"}",content); //断言,判断返回的值是否正确
}
在上面的测试类中,我们用到了这么一个类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;
MockMvcRequestBuilders通过方法得到两类Builder,一个是MockHttpServletRequestBuilder ,一个是MockMultipartHttpServletRequestBuilder (上传文件)
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 param(String name,String... values):请求传入参数
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):请求的后处理器,用于自定义一些请求处理的扩展点;
这块上传文件的大伙应该经常用
MockMultipartHttpServletRequestBuilder继承自MockHttpServletRequestBuilder,又提供了如下API:
MockMultipartHttpServletRequestBuilder file(String name, byte[] content)/MockMultipartHttpServletRequestBuilder file(MockMultipartFile file):指定要上传的文件;
调用MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,通过ResultActions完成如下三件事:
ResultActions andExpect(ResultMatcher matcher) :添加验证断言来判断执行请求后的结果是否是预期的;
ResultActions andDo(ResultHandler handler) :添加结果处理器,用于对验证成功后执行的动作,如输出下请求/结果信息用于调试;
MvcResult andReturn() :返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理;
ResultMatcher用来匹配执行完请求后的结果验证,其就一个match(MvcResult result)断言方法,如果匹配失败将抛出相应的异常;此类案例中并为使用,请自行查看。具体提供以下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);