springmvc之单元测试(MockMvc)-独⽴测试
spring mvc测试框架提供了两种⽅式,独⽴安装和集成Web环境测试(此种⽅式并不会集成真正的web环境,⽽是通过相应的Mock API进⾏模拟测试,⽆须启动服务器)
1、mockMvc.perform执⾏⼀个请求;
2、("/user/1")构造⼀个请求
3、ResultActions.andExpect添加执⾏完成后的断⾔
4、ResultActions.andDo添加⼀个结果处理器,表⽰要对结果做点什么事情,⽐如此处使⽤MockMvcResultHandlers.print()输出整个响应结果信息。
5、ResultActions.andReturn表⽰执⾏完成后返回相应的结果。
MockMvcBuilder是⽤来构造MockMvc的构造器,其主要有两个实现:StandaloneMockMvcBuilder和
DefaultMockMvcBuilder,StandaloneMockMvcBuilder继承了DefaultMockMvcBuilder。直接使⽤静态⼯⼚MockMvcBuilders创建即可:MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下⽂获取相应的控制器并得到相应的MockMvc;
springboot和过滤器
MockMvcBuilders. controllers):通过参数指定⼀组控制器,这样就不需要从上下⽂获取了;
其中DefaultMockMvcBuilder还提供了如下API:
filters)/addFilter(Filter filter, urlPatterns):添加javax.servlet.Filter过滤器
defaultRequest(RequestBuilder requestBuilder):默认的RequestBuilder,每次执⾏时会合并到⾃定义的RequestBuilder中,即提供公共请求数据的;
alwaysExpect(ResultMatcher resultMatcher):定义全局的结果验证器,即每次执⾏请求时都进⾏验证的规则;
alwaysDo(ResultHandler resultHandler):定义全局结果处理器,即每次请求时都进⾏结果处理;
dispatchOptions:DispatcherServlet是否分发OPTIONS请求⽅法到控制器;
StandaloneMockMvcBuilder继承了DefaultMockMvcBuilder,⼜提供了如下API:
setMessageConverters(HttpMessageConverter<?>...messageConverters):设置HTTP消息转换器;
setValidator(Validator validator):设置验证器;
setConversionService(FormattingConversionService conversionService):设置转换服务;
interceptors)/addMappedInterceptors(String[] pathPatterns, interceptors):添加spring mvc;
setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager):设置内容协商管理器;setAsyncRequestTimeout(long timeout):设置异步超时时间;
argumentResolvers):设置⾃定义控制器⽅法参数解析器; handlers):设置⾃定义控制器⽅法返回值处理器;setHandlerExceptionResolvers(List<HandlerExceptionResolver>
exceptionResolvers)/ exceptionResolvers):设置异常解析器;solvers):设置视图解析器;
setSingleView(View view):设置单个视图,即视图解析时总是解析到这⼀个(仅适⽤于只有⼀个视图的
情况);
setLocaleResolver(LocaleResolver localeResolver):设置Local解析器;
setFlashMapManager(FlashMapManager flashMapManager):设置FlashMapManager,如存储重定向数据;setUseSuffixPatternMatch(boolean useSuffixPatternMatch):设置是否是后缀模式匹配,如“/user”是否匹配"/user.*",默认真即匹配;setUseTrailingSlashPatternMatch(boolean useTrailingSlashPatternMatch):设置是否⾃动后缀路径模式匹配,如“/user”是否匹配“/user/”,默认真即匹配;
addPlaceHolderValue(String name, String value) :添加request mapping中的占位符替代;
因为StandaloneMockMvcBuilder不会加载Spring MVC配置⽂件,因此就不会注册我们需要的⼀些组件,因此就提供了如上API⽤于注册我们需要的相应组件。
  perform:执⾏⼀个RequestBuilder请求,会⾃动执⾏SpringMVC的流程并映射到相应的控制器执⾏处理;
  andExpect:添加ResultMatcher验证规则,验证控制器执⾏完成后结果是否正确;
  andDo:添加ResultHandler结果处理器,⽐如调试时打印结果到控制台;
  andReturn:最后返回相应的MvcResult;然后进⾏⾃定义验证/进⾏下⼀步的异步处理;
MockMvcRequestBuilders主要API:
MockHttpServletRequestBuilder get(String urlTemplate, urlVariables):根据uri模板和uri变量值得到⼀个GET请求⽅式的MockHttpServletRequestBuilder;如get("/user/{id}", 1L);
MockHttpServletRequestBuilder post(String urlTemplate, urlVariables):同get类似,但是是POST⽅法;MockHttpServletRequestBuilder put(String urlTemplate, urlVariables):同get类似,但是是PUT⽅法;MockHttpServletRequestBuilder delete(String urlTemplate, urlVariables) :同get类似,但是是DELETE⽅法;MockHttpServletRequestBuilder options(String urlTemplate, urlVariables):同get类似,但是是OPTIONS⽅法;
ResultActions
调⽤MockMvc.perform(RequestBuilder requestBuilder)后将得到ResultActions,通过ResultActions完成如下三件事:
ResultActions andExpect(ResultMatcher matcher) :添加验证断⾔来判断执⾏请求后的结果是否是预期的;
ResultActions andDo(ResultHandler handler) :添加结果处理器,⽤于对验证成功后执⾏的动作,如输出下请求/结果信息⽤于调试;MvcResult andReturn() :返回验证成功后的MvcResult;⽤于⾃定义验证/下⼀步的异步处理;(主要是拿到结果进⼀步做⾃定义断⾔)
1. String requestBody = "{\"id\":1, \"name\":\"zhang\"}";
2. mockMvc.perform(post("/user")
3.            .contentType(MediaType.APPLICATION_JSON).content(requestBody)
4.            .accept(MediaType.APPLICATION_JSON)) //执⾏请求
5.        .andExpect(content().contentType(MediaType.APPLICATION_JSON)) //验证响应contentType
6.        .andExpect(jsonPath("$.id").value(1)); //使⽤Json path验证JSON 请参考goessner/articles/JsonPath/
7.
8. String errorBody = "{id:1, name:zhang}";
9. MvcResult result = mockMvc.perform(post("/user")
10.        .contentType(MediaType.APPLICATION_JSON).content(errorBody)
11.        .accept(MediaType.APPLICATION_JSON)) //执⾏请求
12.        .andExpect(status().isBadRequest()) //400错误请求
13.        .andReturn();
import org.junit.Before;
import org.junit.runner.RunWith;
import org.junit.Test;
import org.springframework.boot.SpringBootConfiguration;
import org.st.SpringApplicationConfiguration;
import org.springframework.http.MediaType;
import k.web.MockSessionCookieConfig;
import st.context.junit4.SpringJUnit4ClassRunner;
import st.context.web.WebAppConfiguration;
import st.web.servlet.MockMvc;
import st.web.servlet.RequestBuilder;
import st.quest.MockMvcRequestBuilders;
import st.sult.MockMvcResultHandlers;
import st.web.servlet.setup.MockMvcBuilders;
import ller.HelloController;
import ller.TestController;
import java.nio.charset.Charset;
import static org.hamcrest.Matchers.equalTo;
import static st.quest.MockMvcRequestBuilders.*;
import static st.t;
import static st.sult.MockMvcResultMatchers.status;
/**
* Created by pinker on 2016/10/26.
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MockSessionCookieConfig.class)
@WebAppConfiguration
public class TestJunit {
private MockMvc mvc;
@Before
public void setUp() throws Exception {
mvc = MockMvcBuilders.standaloneSetup(new HelloController(), new TestController()).build();    }
@Test
public void testHelloController() throws Exception {
mvc.("/hello").accept(MediaType.APPLICATION_JSON))                .andExpect(status().isOk())
.andExpect(content().string(equalTo("Hello")));
}
@Test
public void testController() throws Exception {
//get查⼀下列表应该为空。
RequestBuilder request = null;
request = get("/user");
mvc.perform(request)
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().string(equalTo("[]")));
//插⼊⼀个数据
request = post("/user").param("id", "2").param("name", "HS").param("age", "24");
mvc.perform(request)
.andDo(MockMvcResultHandlers.print())
.
andExpect(content().string(equalTo("success")));
//检查刚才插⼊的数据
request = get("/user");
mvc.perform(request)
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().string(equalTo("[{\"id\":2,\"name\":\"HS\",\"age\":24}]")));
//测试put⽅法
request = put("/user/2")
.param("name", "HGod")
.param("age", "24");
mvc.perform(request)
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isOk())
.andExpect(content().string(equalTo("success!")));
//测试获得⼀个⽤户的get⽅法
request=get("/user/2");
mvc.perform(request)
.andDo(MockMvcResultHandlers.print())
.andExpect(content().string(equalTo("{\"id\":2,\"name\":\"HGod\",\"age\":24}")));
//测试删除⽤户
request=delete("/user/2");
mvc.perform(request)
.andDo(MockMvcResultHandlers.print())
.andExpect(content().string(equalTo("success")))
.andReturn();
}
}