在springmvc中一般的测试用例都是测试service层,今天我来演示下如何使用springmvc mock直接测试controller层代码。

1.什么是mock测试?

mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。

2.为什么要使用mock测试?

使用Mock Object进行测试,主要是用来模拟那些在应用中不容易构造(如HttpServletRequest必须在Servlet容器中才能构造出来)或者比较复杂的对象(如JDBC中的ResultSet对象)从而使测试顺利进行的工具。

3.常用注解

RunWith(SpringJUnit4ClassRunner.class): 表示使用Spring Test组件进行单元测试;

WebAppConfiguratio: 使用这个annotation会在跑单元测试的时候真实的启一个web服务,然后开始调用Controller的Rest API,待单元测试跑完之后再将web服务停掉;

ContextConfiguration: 指定Bean的配置文件信息,可以有多种方式,这个例子使用的是文件路径形式,如果有多个配置文件,可以将括号中的信息配置为一个字符串数组来表示;

4.安装测试环境
spring mvc测试框架提供了两种方式,独立安装和集成Web环境测试(此种方式并不会集成真正的web环境,而是通过相应的Mock API进行模拟测试,无须启动服务器)。

  • 独立安装测试方式

MockMvcBuilders.standaloneSetup(Object... controllers):通过参数指定一组控制器,这样就不需要从上下文获取了;

主要是两个步骤:
(1)首先自己创建相应的控制器,注入相应的依赖
(2)通过MockMvcBuilders.standaloneSetup模拟一个Mvc测试环境,通过build得到一个MockMvc

代码如下:

  1. package com.xfs.test;
  2.  
  3. import org.junit.Assert;
  4. import org.junit.Before;
  5. import org.junit.Test;
  6. import org.springframework.test.web.servlet.MockMvc;
  7. import org.springframework.test.web.servlet.MvcResult;
  8. import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
  9. import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
  10. import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
  11. import org.springframework.test.web.servlet.setup.MockMvcBuilders;
  12.  
  13. import com.alibaba.fastjson.JSON;
  14. import com.alibaba.fastjson.JSONObject;
  15. import com.xfs.web.controller.APIController;
  16.  
  17. /**
  18. * 独立安装测试方式 springmvc mock测试
  19. *
  20. * @author admin
  21. *
  22. * 2017年11月23日 上午10:39:49
  23. */
  24. public class TestApiOne {
  25.  
  26. private MockMvc mockMvc;
  27.  
  28. @Before
  29. public void setUp() {
  30. APIController apiController = new APIController();
  31. mockMvc = MockMvcBuilders.standaloneSetup(apiController).build();
  32. }
  33.  
  34. @Test
  35. public void testGetSequence() {
  36. try {
  37. MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/api/getSequence"))
  38. .andExpect(MockMvcResultMatchers.status().is(200))
  39. .andDo(MockMvcResultHandlers.print())
  40. .andReturn();
  41. int status = mvcResult.getResponse().getStatus();
  42. System.out.println("请求状态码:" + status);
  43. String result = mvcResult.getResponse().getContentAsString();
  44. System.out.println("接口返回结果:" + result);
  45. JSONObject resultObj = JSON.parseObject(result);
  46. // 判断接口返回json中success字段是否为true
  47. Assert.assertTrue(resultObj.getBooleanValue("success"));
  48. } catch (Exception e) {
  49. e.printStackTrace();
  50. }
  51. }
  52.  
  53. }

请求结果如下:

  • 集成Web环境方式

MockMvcBuilders.webAppContextSetup(WebApplicationContext context):指定WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的MockMvc;

主要是三个步骤:

(1)@WebAppConfiguration:测试环境使用,用来表示测试环境使用的ApplicationContext将是WebApplicationContext类型的;value指定web应用的根
(2)通过@Autowired WebApplicationContext wac:注入web环境的ApplicationContext容器
(3)然后通过MockMvcBuilders.webAppContextSetup(wac).build()创建一个MockMvc进行测试

代码如下:

  1. package com.xfs.test;
  2.  
  3. import org.junit.Assert;
  4. import org.junit.Before;
  5. import org.junit.Test;
  6. import org.junit.runner.RunWith;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.mock.web.MockHttpSession;
  9. import org.springframework.test.context.ContextConfiguration;
  10. import org.springframework.test.context.junit4.AbstractJUnit4SpringContextTests;
  11. import org.springframework.test.context.web.WebAppConfiguration;
  12. import org.springframework.test.web.servlet.MockMvc;
  13. import org.springframework.test.web.servlet.MvcResult;
  14. import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
  15. import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
  16. import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
  17. import org.springframework.test.web.servlet.setup.MockMvcBuilders;
  18. import org.springframework.web.context.WebApplicationContext;
  19.  
  20. import com.alibaba.fastjson.JSON;
  21. import com.alibaba.fastjson.JSONObject;
  22.  
  23. /**
  24. * 集成Web环境方式 springmvc mock测试
  25. *
  26. * @author admin
  27. *
  28. * 2017年11月23日 上午11:12:43
  29. */
  30. @RunWith(JUnit4ClassRunner.class)
  31. @WebAppConfiguration
  32. @ContextConfiguration(locations = { "classpath*:spring/*.xml" })
  33. public class TestApiTwo extends AbstractJUnit4SpringContextTests {
  34.  
  35. @Autowired
  36. public WebApplicationContext wac;
  37.  
  38. public MockMvc mockMvc;
  39.  
  40. public MockHttpSession session;
  41.  
  42. @Before
  43. public void before() throws Exception {
  44. mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
  45. }
  46.  
  47. @Test
  48. public void testGetSequence() {
  49. try {
  50. MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.post("/api/getSequence"))
  51. .andExpect(MockMvcResultMatchers.status().is(200))
  52. .andDo(MockMvcResultHandlers.print())
  53. .andReturn();
  54. int status = mvcResult.getResponse().getStatus();
  55. System.out.println("请求状态码:" + status);
  56. String result = mvcResult.getResponse().getContentAsString();
  57. System.out.println("接口返回结果:" + result);
  58. JSONObject resultObj = JSON.parseObject(result);
  59. // 判断接口返回json中success字段是否为true
  60. Assert.assertTrue(resultObj.getBooleanValue("success"));
  61. } catch (Exception e) {
  62. e.printStackTrace();
  63. }
  64. }
  65.  
  66. }

运行结果和上面独立测试时候一样。

总结:

整个过程:
1、mockMvc.perform执行一个请求;
2、MockMvcRequestBuilders.get("/user/1")构造一个请求
3、ResultActions.andExpect添加执行完成后的断言
4、ResultActions.andDo添加一个结果处理器,表示要对结果做点什么事情,比如此处使用MockMvcResultHandlers.print()输出整个响应结果信息。
5、ResultActions.andReturn表示执行完成后返回相应的结果。

整个测试过程非常有规律:
1、准备测试环境
2、通过MockMvc执行请求
3、添加验证断言
4、添加结果处理器
5、得到MvcResult进行自定义断言/进行下一步的异步请求
6、卸载测试环境

参考:

https://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/htmlsingle/#spring-mvc-test-framework

Spring MVC如何测试Controller(使用springmvc mock测试)的更多相关文章

  1. Spring MVC 环境搭建(maven+SpringMVC+mybatis+Freemarker)

    Spring MVC 环境搭建(maven+SpringMVC+mybatis+Freemarker) 一.准备工作 1.Eclipse Java EE IDE(4.4.1) 2.JDK 3.Tomc ...

  2. SpringMVC Mock测试

    什么是mock测试? 在测试过程中,对于某些不容易构成或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法,就是Mock测试. Servlet.Request.Response等Servle ...

  3. Spring MVC基于注解@Controller和@RequestMapping开发的一个例子

    1.创建web项目 2.在springmvc的配置文件中指定注解驱动,配置扫描器 在 Spring MVC 中使用扫描机制找到应用中所有基于注解的控制器类,所以,为了让控制器类被 Spring MVC ...

  4. Spring MVC基本配置@controller和@RequestMapping解释

    一:配置web.xml 1)问题:spring项目中有多个配置文件mvc.xml   dao.xml 2)解决:在web.xml中 <init-param> <param-name& ...

  5. 如何对Spring MVC中的Controller进行单元测试

    对Controller进行单元测试是Spring框架原生就支持的能力,它可以模拟HTTP客户端发起对服务地址的请求,可以不用借助于诸如Postman这样的外部工具就能完成对接口的测试. 具体来讲,是由 ...

  6. Spring MVC 注解之controller层

    第一层注解:@Controller 和 @RestController. 这两个注解的作用是:处理页面的HTTP请求,不同点 @RestController相当于@Controller +@Respo ...

  7. Spring MVC中的Controller是Serlvet吗?

    1. Controller不是Servlet DispatcherServler是Spring MVC中的唯一Servlet,(这点可通过查看FrameworkServlet的子类确认) Servle ...

  8. Spring Mvc 在非controller层 实现获取request对象

    一般我们在Controller层,会编写类似这样的方法 @Controller @RequestMapping(value="/detail") public class GetU ...

  9. Spring MVC入门(一)—— SpringMVC的执行流程与常用注解

    一.什么是SpringMVC SpringMVC就是类似于Struts2的mvc框架,属于SpringFrameWork的后续产品.在模型层中与视图层的交互部分. springMVC执行流程: 二.常 ...

随机推荐

  1. Spring+Spring MVC+MyBatis框架集成

    目录 一.新建一个基于Maven的Web项目 二.创建数据库与表 三.添加依赖包 四.新建POJO实体层 五.新建MyBatis SQL映射层 六.JUnit测试数据访问 七.完成Spring整合My ...

  2. JSP技术介绍

    1. 技术介绍 JSP即Java Server Page,中文全称是Java服务器语言.它是由Sun Microsystems公司倡导.许多公司参与建立的一种动态网页技术标准,它在动态网页的建设中有强 ...

  3. windows中更换Jdk版本不生效

    本机已经安装了jdk1.7,而比较早期的项目需要依赖jdk1.6,于是同时在本机安装了jdk1.6和jdk1.7. 安装jdk1.6前,执行java -version得到 C:\Users\liuxi ...

  4. [转载] Netty

    转载自http://lippeng.iteye.com/blog/1907279 Netty是什么? 本质:JBoss做的一个Jar包 目的:快速开发高性能.高可靠性的网络服务器和客户端程序 优点:提 ...

  5. CentOS6.9编译安装Nginx1.12

    1:安装必要的库 Bash yum install gc gcc gcc-c++ pcre-devel zlib-devel openssl-devel 2:创建Nginx用户和组 Bash grou ...

  6. jQuery与别的js框架冲突

    jQuery.noConflict()运行这个函数将变量$的控制权让渡给第一个实现它的那个库. 这有助于确保jQuery不会与其他库的$对象发生冲突. <script type="te ...

  7. 《Android源码设计模式》学习笔记之ImageLoader

    微信公众号:CodingAndroid cnblog:http://www.cnblogs.com/angel88/ CSDN:http://blog.csdn.net/xinpengfei521 需 ...

  8. 在centos上搭建SVN服务器和MySQL

    ----------搭建MySQL--------------- 1.查看yum库中的mysql yum list | grep mysql //查看yum库中的mysql 2.选择需要的mysql进 ...

  9. 用lua+redis实现一个简单的计数器功能 (一)

    首先安装环境 依赖环境有 luajit http://luajit.org ngx_devel_kit https://github.com/simpl/ngx_devel_kit echo-ngin ...

  10. 已有模板与tp框架结合

    具体实现步骤: ①复制模板文件到view指定文件目录: ②复制css.js.img到view指定文件目录: ③把静态资源(css.js.img)文件的路径设置为“常量”信息(在index.php入口文 ...