spring-test單元測試(三)-spring mvc請求測試

上篇文章中咱們介紹瞭如何在struts環境下,進行模擬action的請求測試,以及咱們使用了EasyMock框架,來模擬對象的行爲。這篇文章咱們會繼續介紹spring mvc環境下如何對controller進行單元測試。另外咱們帶來一種全新的mock框架mockitojava

 

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使用說明

@Mock

private TestService testService;
若是該對象須要mock,則加上此Annotate,在這裏咱們就是要模擬testService的query()行爲
@InjectMocks 
MyController myController;

使mock對象的使用類能夠注入mock對象,在這裏myController使用了testService(mock對象),因此在MyController此加上此Annotate

 

this.mockMvc = MockMvcBuilders.standaloneSetup(myController).build();//這個對象是Controller單元測試的關鍵

 

還有幾點重要說明:

  • mockMvc.perform: 發起一個http請求。
  • post(url): 表示一個post請求,url對應的是Controller中被測方法的Rest url。
  • param(key, value): 表示一個request parameter,方法參數是key和value。
  • andDo(print()): 表示打印出request和response的詳細信息,便於調試。
  • andExpect(status().isOk()): 表示指望返回的Response Status是200。
  • andExpect(content().string(is(expectstring)): 表示指望返回的Response Body內容是指望的字符串。

 

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使用更加簡便。

相關文章
相關標籤/搜索