对Spring MVC接口进行Mock测试( 二 )
构建请求构建请求由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 = []获取返回结果如果你希望进一步处理响应的结果 , 也可以通过ResultActions#andReturn()拿到MvcResult类型的结果进行进一步的处理 。
完整的测试过程通常andExpect是我们必然会选择的 , 而andDo和andReturn在某些场景下会有用 , 它们两个是可选的 。 我们把上面的连在一起 。
@AutowiredMockMvc mockMvc;@SneakyThrows@Testvoid contextLoads() {mockMvc.perform(MockMvcRequestBuilders.get("/foo/user").param("name", "felord.cn").param("age", "18").header("Api-Version", "v1")).andExpect(ResultMatcher.matchAll(status().isOk(),content().contentType(MediaType.APPLICATION_JSON),jsonPath("$.version", Is.is("v1")))).andDo(MockMvcResultHandlers.print());}这种流式的接口单元测试从语义上看也是比较好理解的 , 你可以使用各种断言、正例、反例测试你的接口 , 最终让你的接口更加健壮 。
5. 总结一旦你熟练了这种方式 , 你编写的接口将更加具有权威性而不会再漏洞百出 , 甚至有时候你也可以使用Mock来设计接口 , 使之更加贴合业务 。 所以CRUD不是完全没有技术含量 , 高质量高效率的CRUD往往需要这种工程化的单元测试来支撑 。 好了今天的分享就到这里 , 我是:码农小胖哥 , 多多关注 , 多多支持 。
点击了解更多更加精彩 。
- 纠结|硬杠红米Note9Pro?iQOO Z1跌至1575,对比之后纠结了!
- 对手|一加9Pro全面曝光,或是小米11最大对手
- 作家|逾万名作家联名反对亚马逊有声书轻松退换政策
- 芯片|华米GTS2mini和红米手表哪个好 参数功能配置对比
- 速度|华为P50Pro或采用很吓人的拍照技术:液体镜头让对焦速度更快
- 时尚先生|小米雷军成2020年最出圈企业家:获时尚双刊年度人物
- 电信|巴西电信协会及运营商发文 反对限制华为5G
- 华为|骁龙870和骁龙855区别都是7nm芯片吗 性能对比评测
- 区企联企协|谋求更高质量的转型发展!区企联企协与区科技局成功举办科技考察对接活动
- 中国|对越南新增投资18亿?把30%的生产线转移?富士康真要跑了?
