转(抄)载(袭)自:https://blog.csdn.net/qq_25551573/article/details/82629896
看不进去,所以手抄一遍
基本上会初步使用了,还需要加强常用测试、自定义测试(断言)
一、为何使用MockMvc?
对模块集成,建立HTTP client测试很麻烦
MockMvc实现了对HTTP请求的模拟……提供了验证工具,验证同意方便
二、测试逻辑
1.MockMvcBuilder构造MockMvc的构造器
2.mockMvc调用perform,执行一个RequestBuilder请求,调用controller的业务处理逻辑
3.perform返回ResultActions,返回操作结果,通过ResultActions,提供了统一的验证方式
4.使用StatusResultMatchers对请求结果进行验证
5.使用ContentResultMatchers对请求返回的内容进行验证
- 整个测试过程非常有规律:
- 1、准备测试环境
- 2、通过MockMvc执行请求
- 3.1、添加验证断言
- 3.2、添加结果处理器
- 3.3、得到MvcResult进行自定义断言/进行下一步的异步请求
- 4、卸载测试环境
三、测试用例
package com.example.demo;
import com.example.demo.web.HelloController;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {
private MockMvc mvc;
@Before
public void setUp() throws Exception{
mvc = MockMvcBuilders.standaloneSetup(
new HelloController()
).build();
}
@Test
public void getHello() throws Exception {
String contentAsString = mvc.perform(
MockMvcRequestBuilders.get("/hello")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_JSON)
.param("name", "abc")
.param("age", "22")
)
.andExpect(status().isOk())
.andExpect(content().string(equalTo("hello world!")))
.andDo(print()).andReturn().getResponse().getContentAsString();
System.out.println(contentAsString);
}
}
四、注解以及方法说明
MockMvcBuilder
MockMvc是spring测试下的一个非常好用的类,他们的初始化需要在setUp中进行。
MockMvcBuilder是用来构造MockMvc的构造器,其主要有两个实现:
- StandaloneMockMvcBuilder
- DefaultMockMvcbuilder
前者继承了后者
- MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下文获取相应的公职器并得到相应的MockMvc;
- MockMvcBuilders.standloneSetup(Object...controllers):通过参数指定一组控制器,这样就不需要从上下文获取了,比如this.mockMvc = MockMvcBuilders.standaloneSetup(this.controller).build();
上面是第二种写法,下面是第一种的写法
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration({"classpath:applicationContext.xml"})
@PropertySource("classpath:application.properties")
public class ControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
//该方法在每个方法执行之前都会执行一遍
@Before
public void setUp() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).build();
}
@Test
public void longRentDetails() throws Exception {
String responseString = mockMvc.perform(
MockMvcRequestBuilders.get("/longRentDetails") //请求的url,请求的方法是get
.contentType(MediaType.APPLICATION_JSON)//发送数据的格式
.param("applyNo", "1536315") //添加参数(可以添加多个)
.param("batchNo", "153631515780") //添加参数(可以添加多个)
)
.andExpect(status().isOk()) //返回的状态是200
.andDo(print()) //打印出请求和相应的内容
.andReturn().getResponse().getContentAsString(); //将相应的数据转换为字符串
System.out.println("-----返回的json = " + responseString);
}
}
这些Builder还提供了其他的api,还可以查看官方文档:
MockMvcRequestbuilders
从名字可以看出,RequestBuilders用来构建请求的,其提供了一个方法builderRequest(ServletContext servletContext)用于构建MockHttpServletRequest;其主要有两个子类MockHttpServletRequestBuilder和MockMultipartHttpServletRequestbuilder(如文件上传使用),即用来Mock客户端请求需要的所有数据。
主要API:
- MockHttpServletRequestBuilder get(String urlTemplate,Object…urlVariables):根据uri模板和uri变量值得到一个GET请求方式的RequestBuilder,如果在controller的方法中method选择的是RequestMethod.GET,那在controllerTest中对应的就要使用MockMvcRequestBuilders.get。
- post(String urlTemplate,Object...urlBariables):同get类似,但是是POST方法;
- put(String urlTemplate,Object...urlVariables):同get类似,但是是PUT方法;
- delete(String urlTemplate…………
- options(Sting ……………
ResultActions
调用MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,对REsultActions有以下三种处理:
- ResultActions.andExpect:添加执行完成后的断言。添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;
- ResultActions.andDo:调价一个结果处理器,比如使用.andDo(MockMvcResultHandlers.print())输出整个相应结果信息,可以在调试的时候使用。(备注)
- ResultActions.andReturn:表示执行完成后返回相应的结果
备注:
ResultHandler用于对处理的结果进行相应的处理的,比如输出整个请求/响应等信息方便调试,Spring mvc测试框架提供了MockM找ResultHandles静态工厂方法,该工厂提供了ResultHandler print()返回一个输出MvcResult详细信息到控制台的ResultHandler实现。
ResultMatchers
ResultMatchers用来匹配执行完成请求后的结果验证,其就有一个match(MvcResult result)断言方法,如果匹配失败将抛出相应的异常,spring mvc测试框架提供了很多***ResultMatchers来满足测试需求。具体百度。
百度结果:
这个看起来不错,还需要仔细研究
转载自:https://www.cnblogs.com/lyy-2016/p/6122144.html
五 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"));
MvcResult
即执行完控制器后得到的整个结果,并不仅仅是返回值,其包含了测试时需要的所有信息。
- MockHttpServletRequest getRequest():得到执行的请求;
- MockHttpServletResponse getREsponse():得到执行后的响应;
- Object getHandler():得到执行的处理器,一般就是控制器;
- HandlerInterceptor[] getInterceptors():得到对处理器进行拦截的拦截器;
ModelAndView getModelAndView():得到执行后的ModelAndView;
Exception getResolvedException():得到HandlerExceptionResolver解析后的异常;
FlashMap getFlashMap():得到FlashMap;
Object getAsyncResult()/Object getAsyncResult(long timeout):得到异步执行的结果;