zoukankan      html  css  js  c++  java
  • Spring学习之旅(十)--MockMvc

    在之前的 Spring学习之旅(八)--SpringMVC请求参数 我们是通过在控制台输出来验证参数是否正确,但是这样做实在是太耗时间了,我们今天来学习下 MockMvc,它可以让我们不需要启动项目就能调用接口并验证接口返回结果是否符合我们的预期。

    为何使用MockMvc?

    MockMvc 实现了对 Http 请求的模拟,能够直接使用网络的形式,实现 Controller 的调用,这样可以使得测试速度快、不依赖网络环境,而且提供了一套验证的工具,这样可以使得请求的验证统一而且很方便。

    如何使用 MockMvc

    MockMvcBuilder 是用来构造 MockMvc 的构造器,主要有两个实现:

    • StandaloneMockMvcBuilder
    • DefaultMockMvcBuilder

    分别对应两种测试方式,即独立安装和集成 Web 环境测试(此种方式并不会集成真正的 web 环境,而是通过相应的 Mock API 进行模拟测试,无须启动服务器)。对于我们来说直接使用静态工厂 MockMvcBuilders 创建即可。

    集成Web环境方式

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

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = RootConfig.class)
    @WebAppConfiguration
    public class RequestParameterControllerTest {
    
        @Autowired
        private WebApplicationContext wac;
    
        private MockMvc mockMvc;
    
        @Before
        public void setUp() {
            mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
        }
    }
    

    独立测试方式

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

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = RootConfig.class)
    @WebAppConfiguration
    public class RequestParameterControllerTest {
    
        @Autowired
        private WebApplicationContext wac;
    
        private MockMvc mockMvc;
    
        @Before
        public void setUp() {
            mockMvc = MockMvcBuilders.standaloneSetup(new RequestParameterController()).build();
        }
    }
    

    实例

    Controller:

    @Controller
    public class RequestParameterController {
    
        @RequestMapping("/toInt")
        @ResponseBody
        public int toInt(int value) {
            return  value;
        }
    }
    

    单元测试:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = RootConfig.class)
    @WebAppConfiguration
    public class RequestParameterControllerTest {
    
        @Autowired
        private WebApplicationContext wac;
    
        private MockMvc mockMvc;
    
        @Before
        public void setUp() {
            mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
        }
    
        @Test
        public void toInt() throws Exception {
            mockMvc.perform(
                    // 发送 GET 请求
                    MockMvcRequestBuilders.get("/toInteger?value=3"))
                    // 判断HTTP响应码
                    .andExpect(MockMvcResultMatchers.status().isOk())
                    // 判断返回内容是否是预期值
                    .andExpect(MockMvcResultMatchers.content().string("3"))
                    // 输出整个响应结果信息
                    .andDo(MockMvcResultHandlers.print());
        }
        
    }
    

    控制台输出:

    MockHttpServletRequest:
          HTTP Method = GET
          Request URI = /toInteger
           Parameters = {value=[3]}
              Headers = {}
    
    Handler:
                 Type = com.marklogzhu.web.controller.RequestParameterController
    
    Async:
        Async started = false
         Async result = null
    
    Resolved Exception:
                 Type = null
    
    ModelAndView:
            View name = null
                 View = null
                Model = null
    
    FlashMap:
           Attributes = null
    
    MockHttpServletResponse:
               Status = 200
        Error message = null
              Headers = {Content-Type=[text/plain;charset=ISO-8859-1], Content-Length=[1]}
         Content type = text/plain;charset=ISO-8859-1
                 Body = 3
        Forwarded URL = null
       Redirected URL = null
              Cookies = []
    
    Process finished with exit code 0
    

    常用对象

    MockMvcRequestBuilders

    MockMvcRequestBuilders: 用来构建请求。

    方法 作用
    MockHttpServletRequestBuilder get(String urlTemplate, Object... urlVariables) 发送 GET 请求
    MockHttpServletRequestBuilder post(String urlTemplate, Object... urlVariables) 发送 POST 请求
    MockHttpServletRequestBuilder put(String urlTemplate, Object... urlVariables) 发送 PUT 请求
    MockHttpServletRequestBuilder delete(String urlTemplate, Object... urlVariables) 发送 DELETE 请求
    MockHttpServletRequestBuilder options(String urlTemplate, Object... urlVariables) 发送 OPTIONS 请求
    MockHttpServletRequestBuilder request(HttpMethod httpMethod, String urlTemplate, Object... urlVariables) 提供自己的Http请求方法及uri模板和uri变量
    MockMultipartHttpServletRequestBuilder fileUpload(String urlTemplate, Object... urlVariables) 发送文件上传请求
    RequestBuilder asyncDispatch(final MvcResult mvcResult) 创建一个启动异步处理的请求的 MvcResult 进行异步分派的RequestBuilder

    ResultActions

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

    • ResultActions andExpect(ResultMatcher matcher) :添加验证断言来判断执行请求后的结果是否是预期的;
    • ResultActions andDo(ResultHandler handler) :添加结果处理器,用于对验证成功后执行的动作,如输出下请求/结果信息用于调试;
    • MvcResult andReturn() :返回验证成功后的MvcResult;用于自定义验证/下一步的异步处理;

    ResultMatcher

    方法 作用
    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) 得到Json表达式验证器
    ResultMatcher jsonPath(String expression, Matcher matcher) 得到Json表达式验证器
    XpathResultMatchers xpath(String expression, Object... args) 得到Xpath表达式验证器
    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)

    实例

    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()));//错误的请求内容体
    

    文件上传

    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")); //验证视图  
    

    自定义验证

    MvcResult result = mockMvc.perform(get("/user/{id}", 1))//执行请求  
            .andReturn(); //返回MvcResult  
    Assert.assertNotNull(result.getModelAndView().getModel().get("user")); //自定义断言   
    
  • 相关阅读:
    MySQL------Navicat安装与激活
    MySQL------如何将SQLServer文件数据迁移到MySQL
    WinForm------如何跳转另一个窗口,同时关闭当前窗口
    C#------如何判断输入的是否为纯数字
    WinForm------GridControl显示每行的Indicator中的行号
    WinForm------给GridControl添加搜索功能
    WinForm------分页控件dll下载地址
    WinForm------ToolTipController与GridControl的连用
    利用IE/FF的不同识别CSS来使用浏览器兼容问题
    互换两条记录中的字段值方法(有待测试,,)
  • 原文地址:https://www.cnblogs.com/markLogZhu/p/11400483.html
Copyright © 2011-2022 走看看