良好的开发习惯从单元测试开始。基于Web开发的单元测试可以分为三层进行,Controller层的单元测试、Service层的单元测试、Dao层的单元测试。
Jar依赖准备
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
</dependency>
Controller层的单元测试
Controller层的单元测试基类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring-mvc.xml"})
// 配置加载WebApplicationContext的根目录(web资源的根目录),默认值也是:src/main/webapp
@WebAppConfiguration(value = "src/main/webapp")
public class BaseControllerTest {
@Autowired
private WebApplicationContext webApplicationContext;
protected MockMvc mockMvc;
/**
* 初始化SpringmvcController类测试环境
*/
@Before
public void init(){
//加载web容器上下文
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
@ContextConfiguration Spring整合JUnit4测试时,使用该注解引入配置文件,可以配置多个配置文件。如:{ “classpath:/spring1.xml”, “classpath:/spring2.xml” })
Controller层的Get与Post请求的单元测试
@Slf4j
public class HelloControllerTest extends BaseControllerTest {
protected MockHttpSession mockHttpSession;
protected MockHttpServletRequestBuilder mockHttpServletRequestBuilder;
/**
* 做单元测试准备数据
*/
@Before
public void init() {
super.init();
mockHttpSession = new MockHttpSession();
mockHttpSession.setAttribute("sessionKey1", "sessionKey1Value");
}
/**
* 模拟GET请求的单元测试
*
* @throws Exception
*/
@Test
public void helloGetTest() throws Exception {
mockHttpServletRequestBuilder = MockMvcRequestBuilders.get("/hello/info")
// 设置header值
.header("header1", "v1")
.param("key1", "value1")
.param("key2", "value2")
// 设置session
.session(mockHttpSession);
MvcResult mvcResult = mockMvc.perform(mockHttpServletRequestBuilder)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
log.info(mvcResult.getResponse().getContentAsString());
}
/**
* 模拟POST请求的单元测试
*
* @throws Exception
*/
@Test
public void helloPostTest() throws Exception {
String jsonParam = "{\"key1\":\"value1\",\"key2\":\"value2\"}";
mockHttpServletRequestBuilder = MockMvcRequestBuilders.post("/hello/info")
// 设置header值
.header("header1", "v1")
// 以JSON格式传输数据
.contentType(MediaType.APPLICATION_JSON_VALUE)
// POST中的报文体中的数据
.content(jsonParam)
// 设置session
.session(mockHttpSession);
MvcResult mvcResult = mockMvc.perform(mockHttpServletRequestBuilder)
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
log.info(mvcResult.getResponse().getContentAsString());
}
}
对Controller层返回结果添加断言
mockMvc.perform().andExpect(ResultMatcher) 即为对返回结果添加断言,ResultMatcher通过MockMvcResultMatchers的status(),header(),content()等等即可获取。常用的有:
HandlerResultMatchers handler():请求的Handler验证器,比如验证处理器类型/方法名;此处的Handler其实就是处理请求的控制器;
RequestResultMatchers request():得到RequestResultMatchers验证器;
ModelResultMatchers model():得到模型验证器;
ViewResultMatchers view():得到视图验证器;
FlashAttributeResultMatchers flash():得到Flash属性验证;
StatusResultMatchers status():得到响应状态验证器;
HeaderResultMatchers header():得到响应Header验证器;
CookieResultMatchers cookie():得到响应Cookie验证器;
ContentResultMatchers content():得到响应内容验证器;
JsonPathResultMatchers jsonPath(String expression, Object ... args)/ResultMatcher jsonPath(String expression, Matcher matcher):得到Json表达式验证器;
XpathResultMatchers xpath(String expression, Object... args)/XpathResultMatchers xpath(String expression, Map<string, string=""> namespaces, Object... args):得到Xpath表达式验证器;
ResultMatcher forwardedUrl(final String expectedUrl):验证处理完请求后转发的url(绝对匹配);
ResultMatcher forwardedUrlPattern(final String urlPattern):验证处理完请求后转发的url(Ant风格模式匹配,@since spring4);
ResultMatcher redirectedUrl(final String expectedUrl):验证处理完请求后重定向的url(绝对匹配);
ResultMatcher redirectedUrlPattern(final String expectedUrl):验证处理完请求后重定向的url(Ant风格模式匹配,@since spring4);
Service层的单元测试
Service层单元测试的基类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:test/applicationContext.xml"})
public class BaseServiceTest {
}
Service层的单元测试只需要加载Service层所需要的配置即可(service层通常调用Dao层,故也需要Dao层的配置)。
Service层单元测试的示例
public class HelloServiceTest extends BaseServiceTest {
@Autowired
private HelloService helloService;
@Test
public void sample(){
helloService.sample();
}
}











网友评论