zoukankan      html  css  js  c++  java
  • springmvc之单元测试(MockMvc)-独立测试

    spring mvc测试框架提供了两种方式,独立安装和集成Web环境测试(此种方式并不会集成真正的web环境,而是通过相应的Mock API进行模拟测试,无须启动服务器)

    1、mockMvc.perform执行一个请求;

    2、MockMvcRequestBuilders.get("/user/1")构造一个请求

    3、ResultActions.andExpect添加执行完成后的断言

    4、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。

    5、ResultActions.andReturn表示执行完成后返回相应的结果。

    MockMvcBuilder是用来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和DefaultMockMvcBuilder,StandaloneMockMvcBuilder继承了DefaultMockMvcBuilder。直接使用静态工厂MockMvcBuilders创建即可:

    MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的MockMvc;

    MockMvcBuilders.standaloneSetup(Object... controllers):通过参数指定一组控制器,这样就不需要从上下文获取了;

    其中DefaultMockMvcBuilder还提供了如下API:

    addFilters(Filter... filters)/addFilter(Filter filter, String... urlPatterns):添加javax.servlet.Filter过滤器

    defaultRequest(RequestBuilder requestBuilder):默认的RequestBuilder,每次执行时会合并到自定义的RequestBuilder中,即提供公共请求数据的;

    alwaysExpect(ResultMatcher resultMatcher):定义全局的结果验证器,即每次执行请求时都进行验证的规则;

    alwaysDo(ResultHandler resultHandler):定义全局结果处理器,即每次请求时都进行结果处理;

    dispatchOptions:DispatcherServlet是否分发OPTIONS请求方法到控制器;

    StandaloneMockMvcBuilder继承了DefaultMockMvcBuilder,又提供了如下API:

    setMessageConverters(HttpMessageConverter<?>...messageConverters):设置HTTP消息转换器;

    setValidator(Validator validator):设置验证器;

    setConversionService(FormattingConversionService conversionService):设置转换服务;

    addInterceptors(HandlerInterceptor... interceptors)/addMappedInterceptors(String[] pathPatterns, HandlerInterceptor... interceptors):添加spring mvc拦截器;

    setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager):设置内容协商管理器;

    setAsyncRequestTimeout(long timeout):设置异步超时时间;

    setCustomArgumentResolvers(HandlerMethodArgumentResolver... argumentResolvers):设置自定义控制器方法参数解析器;

    setCustomReturnValueHandlers(HandlerMethodReturnValueHandler... handlers):设置自定义控制器方法返回值处理器;

    setHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers)/setHandlerExceptionResolvers(HandlerExceptionResolver... exceptionResolvers):设置异常解析器;

    setViewResolvers(ViewResolver...resolvers):设置视图解析器;

    setSingleView(View view):设置单个视图,即视图解析时总是解析到这一个(仅适用于只有一个视图的情况);

    setLocaleResolver(LocaleResolver localeResolver):设置Local解析器;

    setFlashMapManager(FlashMapManager flashMapManager):设置FlashMapManager,如存储重定向数据;

    setUseSuffixPatternMatch(boolean useSuffixPatternMatch):设置是否是后缀模式匹配,如“/user”是否匹配"/user.*",默认真即匹配;

    setUseTrailingSlashPatternMatch(boolean useTrailingSlashPatternMatch):设置是否自动后缀路径模式匹配,如“/user”是否匹配“/user/”,默认真即匹配;

    addPlaceHolderValue(String name, String value) :添加request mapping中的占位符替代;

    因为StandaloneMockMvcBuilder不会加载Spring MVC配置文件,因此就不会注册我们需要的一些组件,因此就提供了如上API用于注册我们需要的相应组件。

      

      perform:执行一个RequestBuilder请求,会自动执行SpringMVC的流程并映射到相应的控制器执行处理;

      andExpect:添加ResultMatcher验证规则,验证控制器执行完成后结果是否正确;

      andDo:添加ResultHandler结果处理器,比如调试时打印结果到控制台;

      andReturn:最后返回相应的MvcResult;然后进行自定义验证/进行下一步的异步处理;

    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方法;

    ResultActions

    调用MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,通过ResultActions完成如下三件事:

    ResultActions andExpect(ResultMatcher matcher) :添加验证断言来判断执行请求后的结果是否是预期的;

    ResultActions andDo(ResultHandler handler) :添加结果处理器,用于对验证成功后执行的动作,如输出下请求/结果信息用于调试;

    MvcResult andReturn() :返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理;(主要是拿到结果进一步做自定义断言)

    1. String requestBody = "{"id":1, "name":"zhang"}";  
    2. mockMvc.perform(post("/user")  
    3.             .contentType(MediaType.APPLICATION_JSON).content(requestBody)  
    4.             .accept(MediaType.APPLICATION_JSON)) //执行请求  
    5.         .andExpect(content().contentType(MediaType.APPLICATION_JSON)) //验证响应contentType  
    6.         .andExpect(jsonPath("$.id").value(1)); //使用Json path验证JSON 请参考http://goessner.net/articles/JsonPath/  
    7.   
    8. String errorBody = "{id:1, name:zhang}";  
    9. MvcResult result = mockMvc.perform(post("/user")  
    10.         .contentType(MediaType.APPLICATION_JSON).content(errorBody)  
    11.         .accept(MediaType.APPLICATION_JSON)) //执行请求  
    12.         .andExpect(status().isBadRequest()) //400错误请求  
    13.         .andReturn(); 
    import org.junit.Before;
    import org.junit.runner.RunWith;
    import org.junit.Test;
    import org.springframework.boot.SpringBootConfiguration;
    import org.springframework.boot.test.SpringApplicationConfiguration;
    import org.springframework.http.MediaType;
    import org.springframework.mock.web.MockSessionCookieConfig;
    import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
    import org.springframework.test.context.web.WebAppConfiguration;
    import org.springframework.test.web.servlet.MockMvc;
    import org.springframework.test.web.servlet.RequestBuilder;
    import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
    import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
    import org.springframework.test.web.servlet.setup.MockMvcBuilders;
    import org.sselab.controller.HelloController;
    import org.sselab.controller.TestController;

    import java.nio.charset.Charset;

    import static org.hamcrest.Matchers.equalTo;
    import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
    import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

    /**
    * Created by pinker on 2016/10/26.
    */
    @RunWith(SpringJUnit4ClassRunner.class)
    @SpringApplicationConfiguration(classes = MockSessionCookieConfig.class)
    @WebAppConfiguration
    public class TestJunit {
    private MockMvc mvc;

    @Before
    public void setUp() throws Exception {
    mvc = MockMvcBuilders.standaloneSetup(new HelloController(), new TestController()).build();
    }

    @Test
    public void testHelloController() throws Exception {
    mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
    .andExpect(status().isOk())
    .andExpect(content().string(equalTo("Hello")));
    }

    @Test
    public void testController() throws Exception {
    //get查一下列表应该为空。
    RequestBuilder request = null;
    request = get("/user");
    mvc.perform(request)
    .andDo(MockMvcResultHandlers.print())
    .andExpect(status().isOk())
    .andExpect(content().string(equalTo("[]")));
    //插入一个数据
    request = post("/user").param("id", "2").param("name", "HS").param("age", "24");
    mvc.perform(request)
    .andDo(MockMvcResultHandlers.print())
    .andExpect(content().string(equalTo("success")));
    //检查刚才插入的数据
    request = get("/user");
    mvc.perform(request)
    .andDo(MockMvcResultHandlers.print())
    .andExpect(status().isOk())
    .andExpect(content().string(equalTo("[{"id":2,"name":"HS","age":24}]")));
    //测试put方法
    request = put("/user/2")
    .param("name", "HGod")
    .param("age", "24");
    mvc.perform(request)
    .andDo(MockMvcResultHandlers.print())
    .andExpect(status().isOk())
    .andExpect(content().string(equalTo("success!")));
    //测试获得一个用户的get方法
    request=get("/user/2");
    mvc.perform(request)
    .andDo(MockMvcResultHandlers.print())
    .andExpect(content().string(equalTo("{"id":2,"name":"HGod","age":24}")));
    //测试删除用户
    request=delete("/user/2");
    mvc.perform(request)
    .andDo(MockMvcResultHandlers.print())
    .andExpect(content().string(equalTo("success")))
    .andReturn();
    }
    }
  • 相关阅读:
    ubuntu20.04上实现百度Apollo6.0系统的部署
    matplotlib包图例出现中文乱码问题
    微软官方Silverlight 音频播放器 Jonas修整版(silerlight 2.0版)
    SpringCloud总结1
    Java中文长度计算
    注册退出函数:atexit
    函数参数的一种特殊用法
    new与malloc等的区别
    两种多态
    第一章 1.1.2 因特网提供服务的方式
  • 原文地址:https://www.cnblogs.com/xd03122049/p/6001457.html
Copyright © 2011-2022 走看看