上篇文章中咱們介紹瞭如何在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使用更加簡便。