上篇文章中咱们介绍了如何在struts环境下,进行模拟action的请求测试,以及咱们使用了EasyMock框架,来模拟对象的行为。这篇文章咱们会继续介绍spring mvc环境下如何对controller进行单元测试。另外咱们带来一种全新的mock框架mockito。java
1、准备工做,引入如下maven坐标web
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>3.2.3.RELEASE</version> <scope>test</scope> </dependency> <!--mockito用于spirng单元测试--> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>2.2.9</version> <scope>test</scope> </dependency> <!--mockito要依赖eljar包,这个是必定要有的,否则会报异常,见异常图--> <dependency> <groupId>org.glassfish</groupId> <artifactId>javax.el</artifactId> <version>3.0.0</version> <scope>test</scope> </dependency> 固然别忘记了junit,咱们所使用的spring-test框架都是基于junit <!-- junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> </dependency>
2、总体文件spring
全部测试文件,均要求放入test目录下(一种规范)mvc
MyControllerTest.java测试主类app
import com.jd.plugin.web.springmvc.service.TestService; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.servlet.ModelAndView; import static org.hamcrest.core.Is.is; import static org.mockito.Mockito.when; import static org.mockito.Mockito.verify; import staticorg.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import staticorg.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import staticorg.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * Created by wangxindong on 2016/11/24. */ @RunWith(SpringJUnit4ClassRunner.class) //@WebAppConfiguration @ContextConfiguration(locations={"classpath*:/spring-config-dispatcher.xml"}) public class MyControllerTest { private MockMvc mockMvc; @Mock//若是该对象须要mock,则加上此Annotate,在这里咱们就是要模拟testService的query()行为 private TestService testService; @InjectMocks//使mock对象的使用类能够注入mock对象,在这里myController使用了testService(mock对象),因此在MyController此加上此Annotate MyController myController; @Before public void setup() { MockitoAnnotations.initMocks(this); this.mockMvc = MockMvcBuilders.standaloneSetup(myController).build();//这个对象是Controller单元测试的关键 } @Test public voidtestQueryDataFromController() throws Exception{ //静态引入使得很像人类的语言,当...而后返回... when(testService.query("code-1001","name-wangxindong")).thenReturn("成功");//这里模拟行为,返回"成功" 而不是原始的"test-code-name" mockMvc.perform(get("/mytest/query/queryData") .param("code","code-1001") .param("name","name-wangxindong")) .andDo(print()); // .andExpect(status().isOk()).andExpect(content().string(is("{\"status\":\""+ result + "\"}"))); verify(testService).query("code-1001","name-wangxindong"); } }
MyController.java 被测试的controller框架
import com.jd.plugin.web.springmvc.service.TestService; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; /** * Created by wangxindong on 2016/11/24. */ @RequestMapping("/mytest") @Controller public class MyController { @Resource private TestService testService; @RequestMapping(value ="/query/queryData", method = RequestMethod.GET) @ResponseBody public StringqueryData(@RequestParam(required = true, value = "code", defaultValue= "") String code, @RequestParam(value = "name", defaultValue = "")String name, HttpServletRequest request){ System.out.println("code:"+code); System.out.println("name:"+name); String result =testService.query(code,name); return "result"; } }
TestService.java 业务类webapp
/** * Created by wangxindong on 2016/11/24. */ public interface TestService { public String query(Stringcode,String name); }
TestServiceImpl.java业务实现类maven
import com.jd.plugin.web.springmvc.service.TestService; /** * Created by wangxindong on 2016/11/24. */ public class TestServiceImpl implements TestService { public String query(String code,String name) { System.out.println("TestServiceImplcode:"+code); System.out.println("TestServiceImplname:"+name); return "test-code-name"; } }
3、文件逐步说明post
一、Spring Test 组件使用单元测试
@RunWith(SpringJUnit4ClassRunner.class) 表示使用SpringTest组件进行单元测试,这个你们应该都很熟悉了,咱们一直是这样使用的
@ContextConfiguration(locations={"classpath*:/spring-config-dispatcher.xml"})指定bean的配置文件,加载上下文环境,咱们前面的文章都是这样使用的。其实还有一种文件路径的方式,好比:@ContextConfiguration("file:src/main/webapp/WEB-INF/mvc-dispatcher-servlet.xml"),通常我的喜欢第一种方式。
二、mockito使用说明
private TestService testService;
若是该对象须要mock,则加上此Annotate,在这里咱们就是要模拟testService的query()行为
@InjectMocks
MyController myController;
使mock对象的使用类能够注入mock对象,在这里myController使用了testService(mock对象),因此在MyController此加上此Annotate
this.mockMvc = MockMvcBuilders.standaloneSetup(myController).build();//这个对象是Controller单元测试的关键
还有几点重要说明:
4、运行结果,这些都是print()打印出的内容
MockHttpServletRequest:
HTTP Method = GET
Request URI = /mytest/query/queryData
Parameters = {code=[code-1001],name=[name-wangxindong]}
Headers = {}
Handler:
Type =com.jd.plugin.web.springmvc.controller.MyController
Method = public java.lang.Stringcom.jd.plugin.web.springmvc.controller.MyController.queryData(java.lang.String,java.lang.String,javax.servlet.http.HttpServletRequest)
Resolved Exception:
Type = null
ModelAndView:
View name = null
View = null
Model = null
FlashMap:
MockHttpServletResponse:
Status = 200
Error message = null
Headers ={Content-Type=[text/plain;charset=ISO-8859-1], Content-Length=[6]}
Content type =text/plain;charset=ISO-8859-1
Body = result
Forwarded URL = null
Redirected URL = null
Cookies= []
总结,spring mvc的web请求,咱们同样能够经过Spring Test组件来测试。另外mockito这种mock框架来模拟对象行为的时候更加方便,比早先的easymock使用更加简便。