MockMvc单元测试初步使用

转(抄)载(袭)自: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

前者继承了后者

  1. MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下文获取相应的公职器并得到相应的MockMvc;
  2. 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:

  1. MockHttpServletRequestBuilder get(String urlTemplate,Object…urlVariables):根据uri模板和uri变量值得到一个GET请求方式的RequestBuilder,如果在controller的方法中method选择的是RequestMethod.GET,那在controllerTest中对应的就要使用MockMvcRequestBuilders.get。
  2. post(String urlTemplate,Object...urlBariables):同get类似,但是是POST方法;
  3. put(String urlTemplate,Object...urlVariables):同get类似,但是是PUT方法;
  4. delete(String urlTemplate…………
  5. options(Sting ……………

ResultActions

    调用MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,对REsultActions有以下三种处理:

  1. ResultActions.andExpect:添加执行完成后的断言。添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;
  2. ResultActions.andDo:调价一个结果处理器,比如使用.andDo(MockMvcResultHandlers.print())输出整个相应结果信息,可以在调试的时候使用。(备注)
  3. 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):得到异步执行的结果;
     

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值