一个小片段来看spring test中的链式调用

来源:互联网 发布:大掌柜软件免费版 编辑:程序博客网 时间:2024/06/05 17:09

先看看下面的测试代码片段:

  ResultActions actions=mockMvc.perform(requestBuilder);  actions.andExpect(status().isOk())        .andExpect(jsonPath("$.success").value(false))        .andExpect(jsonPath("$.data").doesNotExist())/       .andExpect(content().contentType("application/json;charset=UTF-8"));

代码看起来很简洁和整齐,是不是很酷?这就是所谓的链式调用了......

链式调用的基本原理其实很简单,就是每个方法调用后都返回一个对象引用。

好吧,我们来分析下上面的代码片段,每次调用andExpect都会返回actions对象,它的类型是ResultActions,这是一个接口,要想知道每次调用andExpect到底做了些什么,我们必须看看mockMvc.perform()到底返回了什么,看源码会发现是下面这样的:

public ResultActions perform(RequestBuilder requestBuilder) throws Exception {........               //测试执行后返回的结果final MvcResult mvcResult = new DefaultMvcResult(request, response);...........               return new ResultActions() {@Overridepublic ResultActions andExpect(ResultMatcher matcher) throws Exception {matcher.match(mvcResult);return this;}@Overridepublic ResultActions andDo(ResultHandler handler) throws Exception {handler.handle(mvcResult);return this;}@Overridepublic MvcResult andReturn() {return mvcResult;}};}

可以看到mockMvc.perform()返回的是一个ResultActions类型的匿名类对象,这种返回匿名类对象使得设计非常灵活,spring中存在很多这样的用法。

再来看看匿名类对象中的andExpect方法,它接收一个ResultMatcher 类型的参数,然后调用matcher.match(mvcResult); 这里的mvcResult就是调用测试请求执行后真正的返回结果。

下面来看看status().isOk()是个什么样的ResultMatcher,相关方法都在StatusResultMatchers类中:

public ResultMatcher isOk() {<span style="white-space:pre"></span>return matcher(HttpStatus.OK);}private ResultMatcher matcher(final HttpStatus status) {return new ResultMatcher() {@Overridepublic void match(MvcResult result) {assertEquals("Status", status.value(), result.getResponse().getStatus());}};}

看到了吗,这里又是一个匿名类对象,而在这个对象中才真正去assertEquals。另外,你可能还会注意到actions.andExpect(status().isOk())这句,为什么可以直接调用status()呢,status()方法又不是当前类中的方法?这是因为使用了静态引用 ,即import static,用这种方法可以直接引入类中的静态方法,使得当前类可以像使用自己的方法一样使用其他类中的静态方法,好处是我们的代码看起来更加的简洁。

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


总结一下:spring-test模块中的很多设计是很巧妙的,像本篇中阐述的通过结合返回匿名类对象来达到链式调用的效果很值得我们在设计中加以借鉴。

0 0
原创粉丝点击