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

相关文章
相关标签/搜索