本篇主要是学习在SpringBoot 使用Mock 测试 web API接口。
org.springframework.boot
spring-boot-starter-parent
2.1.0.RELEASE
UTF-8
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-devtools
true
org.springframework.boot
spring-boot-maven-plugin
true
package com.test.controller;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloTest {
private MockMvc mvc;
@Before
public void setUp() throws Exception {
mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
}
@Test
public void getHello() throws Exception {
mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().string(equalTo("Hello World")));
}
}
@RunWith 加载运行测试环境。初始化单元测试类
SpringRunner 与 SpringJUnit4ClassRunner 两者都可以加载测试环境,前者更方便
SpringRunner 继承了 SpringJUnit4ClassRunner 没有做其他扩展实现
@SpringBootTest 声明是使用SprintBootTest,自动加载Spring 上下文环境, 如果不需要spring 上下文环境 ,可以不需要此注解。
第一种创建MockMvc 的方式,不需要WebApplicationContext 来构建。
private MockMvc mvc; @Before public void setUp() throws Exception { mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build(); }
第二种使用WebApplicationContext 进行构建。
private MockMvc mvc ; @Autowired private WebApplicationContext context; @Before public void setUp(){ mvc = MockMvcBuilders.webAppContextSetup(context).build(); }
MockMvc : 负责处理web 请求的处理类 ,是一个final class 。
核心处理方式 perform(), 返回值是一个可操作的结果类,通过RequestBuilder接口 来模拟构造请求信息,包括请求头和请求体。
public ResultActions perform(RequestBuilder requestBuilder) throws Exception
RequestBuilder 由 MockMvcRequestBuilders 通过不同的方法构造其子类来实现的
public static MockHttpServletRequestBuilder get(String urlTemplate, Object... uriVars) {
return new MockHttpServletRequestBuilder(HttpMethod.GET, urlTemplate, uriVars);
}
public static MockHttpServletRequestBuilder get(URI uri) {
return new MockHttpServletRequestBuilder(HttpMethod.GET, uri);
}
public static MockHttpServletRequestBuilder post(String urlTemplate, Object... uriVars) {
return new MockHttpServletRequestBuilder(HttpMethod.POST, urlTemplate, uriVars);
}
public static MockHttpServletRequestBuilder post(URI uri) {
return new MockHttpServletRequestBuilder(HttpMethod.POST, uri);
}
MockMvcRequestBuilders 支持常见的HTTP 请求操作,最常用的就是GET 和POST 方法。
MockMvcRequestBuilders 操作GET ,POST 后返回 MockHttpServletRequestBuilder 类,支持设定请求头信息和请求参数体。
MockHttpServletRequestBuilder builder = new MockHttpServletRequestBuilder();
builder.characterEncoding("");
builder.accept("");
builder.contentType("");
builder.contentType("");
builder.contextPath("");
builder.param(“”);
HTTP 请求头相关设置都有相应的方法。
通过perform() 调用后,会返回ResultActions 对象。
ResultActions 有常使用的3个方法。
return new ResultActions() {
public ResultActions andExpect(ResultMatcher matcher) throws Exception {
matcher.match(mvcResult);
return this;
}
public ResultActions andDo(ResultHandler handler) throws Exception {
handler.handle(mvcResult);
return this;
}
public MvcResult andReturn() {
return mvcResult;
}
};
andExpect 期望值匹配,相当于Assert 操作,就要是检查结果是否符合预期。
MockMvcResultMatchers 进行对期望匹配的结果进行操作。
常用的操作有状态和结果验证。
MockMvcResultMatchers.status().isOk()
MockMvcResultMatchers.content().string(Matchers.containsString("Hello"))
andDo : 返回结果进行其他处理,调用Handler 进行print , log , error 等操作。
调用MockMvcResultHandlers.print() 进行 MvcResult 结果打印。
MockHttpServletRequest:
HTTP Method = GET
Request URI = /hello
Parameters = {}
Headers = {Content-Type=[application/json], Accept=[application/x-www-form-urlencoded]}
Body =
Session Attrs = {}
Handler:
Type = com.neo.controller.HelloController
Method = public java.lang.String com.neo.controller.HelloController.index()
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=[application/x-www-form-urlencoded;charset=UTF-8], Content-Length=[11]}
Content type = application/x-www-form-urlencoded;charset=UTF-8
Body = Hello World
Forwarded URL = null
Redirected URL = null
Cookies = []
addReturn : 返回执行的结果,封装整个请求及响应的内容到MvcResult 中。
MvcResult 是一个接口类。 可以获取整个请求中的相应操作内容
MockHttpServletRequest getRequest();
MockHttpServletResponse getResponse();
@Nullable
Object getHandler();
@Nullable
HandlerInterceptor[] getInterceptors();
@Nullable
ModelAndView getModelAndView();
@Nullable
Exception getResolvedException();
FlashMap getFlashMap();
Object getAsyncResult();
Object getAsyncResult(long var1);
例如 MvcResult 获取某个对象打印: