对Spring MVC接口进行Mock测试( 二 )

4. MockMvc测试集成测试时 , 希望能够通过输入URL对Controller进行测试 , 如果通过启动服务器 , 建立http client进行测试 , 这样会使得测试变得很麻烦 , 比如 , 启动速度慢 , 测试验证不方便 , 依赖网络环境等 , 为了可以对Controller进行测试就引入了MockMvc 。
MockMvc实现了对Http请求的模拟 , 能够直接使用网络的形式 , 转换到Controller的调用 , 这样可以使得测试速度快、不依赖网络环境 , 而且提供了一套验证的工具 , 这样可以使得请求的验证统一而且很方便 。 接下来我们来一步步构造一个测试的模拟请求 , 假设我们存在一个下面这样的接口:
@RestController @RequestMapping("/foo") public class FooController {@Autowiredprivate MyBean myBean; ?@GetMapping("/user")public Map bar(@RequestHeader("Api-Version") String apiVersion, User user) {Map map = new HashMap<>();map.put("test", myBean.bar());map.put("version", apiVersion);map.put("username", user.getName());//todo your businessreturn map;} }参数设定为name=felord.cn --tt-darkmode-color: #809CB9;"> , 那么对应的HTTP报文是这样的:
GET /foo/user?name=felord.cn --tt-darkmode-color: #809CB9;">可以预见的返回值为:
{"test": "bar","version": "v1","username": "felord.cn" }事实上对接口的测试可以分为以下几步 。
构建请求构建请求由MockMvcRequestBuilders负责 , 他提供了请求方法(Method) , 请求头(Header) , 请求体(Body) , 参数(Parameters) , 会话(Session)等所有请求的属性构建 。 /foo/user接口的请求可以转换为:
MockMvcRequestBuilders.get("/foo/user").param("name", "felord.cn").param("age", "18").header("Api-Version", "v1")执行Mock请求然后由MockMvc执行Mock请求:
mockMvc.perform(MockMvcRequestBuilders.get("/foo/user").param("name", "felord.cn").param("age", "18").header("Api-Version", "v1"))对结果进行处理请求结果被封装到ResultActions对象中 , 它封装了多种让我们对Mock请求结果进行处理的方法 。
对结果进行预期期望ResultActions#andExpect(ResultMatcher matcher)方法负责对响应的结果的进行预期期望 , 看看是否符合测试的期望值 。 参数ResultMatcher负责从响应对象中提取我们需要期望的部位进行预期比对 。
假如我们期望接口/foo/user返回的是JSON , 并且HTTP状态为200 , 同时响应体包含了version=v1的值 , 我们应该这么声明:
ResultMatcher.matchAll(MockMvcResultMatchers.status().isOk(),MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON),MockMvcResultMatchers.jsonPath("$.version", Is.is("v1")));JsonPath是一个强大的JSON解析类库 , 请通过其项目仓库了解 。
对响应进行处理ResultActions#andDo(ResultHandler handler)方法负责对整个请求/响应进行打印或者log输出、流输出 , 由MockMvcResultHandlers工具类提供这些方法 。 我们可以通过以上三种途径来查看请求响应的细节 。
例如/foo/user接口:
MockHttpServletRequest:HTTP Method = GETRequest URI = /foo/userParameters = {name=[felord.cn], age=[18]}Headers = [Api-Version:"v1"]Body = nullSession Attrs = {}Handler:Type = cn.felord.xbean.config.FooControllerMethod = cn.felord.xbean.config.FooController#urlEncode(String, Params)Async:Async started = falseAsync result = nullResolved Exception:Type = nullModelAndView:View name = nullView = nullModel = nullFlashMap:Attributes = nullMockHttpServletResponse:Status = 200Error message = nullHeaders = [Content-Type:"application/json"]Content type = application/jsonBody = {"test":"bar","version":"v1","username":"felord.cn"}Forwarded URL = nullRedirected URL = nullCookies = []


推荐阅读