一、前言

在前面的章节我们介绍过 Junit 的使用,也了解过 spring-test,今天我们来了解一个新玩意 -- mock 测试。这里仅仅做一个入门,对返回视图和返回 Json 数据的方法进行测试演示,不会把所有的方法都介绍到,具体文档详见链接:Mock Test,本章节主要讲解以下两部分内容:

1、Mock 测试简介

2、测试用例演示


二、Mock 测试简介

1、什么是 mock 测试

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

  • 虚拟的对象就是 mock 对象。
  • mock 对象就是真实对象在调试期间的代替品。

2、为什么使用 mock 测试

  • 避免开发模块之间的耦合
  • 轻量、简单、灵活

3、MockMVC 介绍

基于 RESTful 风格的 SpringMVC 的测试,我们可以测试完整的 Spring MVC 流程,即从 URL请求到控制器处理,再到视图渲染都可以测试。

1)MockMvcBuilder

MockMvcBuilder 是用来构造 MockMvc 的构造器,其主要有两个实现:StandaloneMockMvcBuilder 和 DefaultMockMvcBuilder,对于我们来说直接使用静态工厂 MockMvcBuilders 创建即可。

2)MockMvcBuilders

负责创建 MockMvcBuilder 对象,有两种创建方式:

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

webAppContextSetup(WebApplicationContext wac):指定 WebApplicationContext,将会从该上下文获取相应的控制器并得到相应的 MockMvc,本章节下面测试用例均使用这种方式创建 MockMvcBuilder 对象。

3)MockMvc

对于服务器端的 SpringMVC 测试支持主入口点。通过 MockMvcBuilder 构造MockMvcBuilder 由 MockMvcBuilders 建造者的静态方法去建造。

核心方法:perform(RequestBuilder rb) -- 执行一个 RequestBuilder 请求,会自动执行SpringMVC 的流程并映射到相应的控制器执行处理,该方法的返回值是一个 ResultActions。

4)ResultActions

(1)andExpect:添加 ResultMatcher 验证规则,验证控制器执行完成后结果是否正确;

(2)andDo:添加 ResultHandler 结果处理器,比如调试时打印结果到控制台;

(3)andReturn:最后返回相应的 MvcResult;然后进行自定义验证/进行下一步的异步处理;

5)MockMvcRequestBuilders

用来构建请求的,其主要有两个子类 MockHttpServletRequestBuilder 和MockMultipartHttpServletRequestBuilder(如文件上传使用),即用来 Mock 客户端请求需要的所有数据。

6)MockMvcResultMatchers

(1)用来匹配执行完请求后的结果验证

(2)如果匹配失败将抛出相应的异常

(3)包含了很多验证 API 方法

7)MockMvcResultHandlers

(1)结果处理器,表示要对结果做点什么事情

(2)比如此处使用 MockMvcResultHandlers.print() 输出整个响应结果信息

8)MvcResult

(1)单元测试执行结果,可以针对执行结果进行自定义验证逻辑。


三、测试用例演示

1、添加依赖

<!-- spring 单元测试组件包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.7.RELEASE</version>
</dependency>
<!-- 单元测试Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- Mock测试使用的json-path依赖 -->
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.2.0</version>
</dependency>

前两个 jar 依赖我们都已经接触过了,对于返回视图方法的测试这两个 jar 依赖已经足够了,第三个 jar 依赖是用于处理返回 Json 数据方法的,这里要明白每个 jar 的具体作用。

2、被测试的方法

@RequestMapping(value = "editItem")
public String editItem(Integer id, Model model) {
Item item = itemService.getItemById(id);
model.addAttribute("item", item);
return "itemEdit";
} @RequestMapping(value = "getItem")
@ResponseBody
public Item getItem(Integer id) {
Item item = itemService.getItemById(id);
return item;
}

这里我们提供了两个方法,一个是返回视图的方法,另一个是返回 Json 数据的方法,下面我们会给出测试类,分别对这两个方法进行测试。

3、测试类:ItemMockTest

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring/*.xml")
@WebAppConfiguration
public class ItemMockTest { @Autowired
private WebApplicationContext context; private MockMvc mockMvc; @Before
public void init() {
mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}
}

这里前两个注解就不再解释了,我们在学习 Spring 与 Junit 整合的时候已经讲解过了,这里说一下第三个注解: @WebAppConfiguration:可以在单元测试的时候,不用启动 Servlet 容器,就可以获取一个 Web 应用上下文。

1)返回视图方法测试

@Test
public void test() throws Exception {
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/editItem").param("id", "1"))
.andExpect(MockMvcResultMatchers.view().name("itemEdit"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print())
.andReturn();
Assert.assertNotNull(result.getModelAndView().getModel().get("item"));
}

这三句代码是我们对结果的期望,最后打印出了结果,说明执行成功,所有期望都达到了,否则会直接报错。从结果中我们就可以看到这个请求测试的情况。

2、返回 Json 数据方法

@Test
public void test1() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/getItem")
.param("id", "1")
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1))
.andExpect(MockMvcResultMatchers.jsonPath("$.name").value("IPhone X"))
.andDo(MockMvcResultHandlers.print())
.andReturn();
}

在这个方法中比较特殊的就是设置 MediaType 类型,因为都是使用 Json 格式,所以设置了 MediaType.APPLICATION_JSON,jsonPath 用于比对期望的数据是否与返回的结果一致,这里需要注意的是 "$.id" 这 key 的种形式。


四、小结

这里只是用到了 MockMvc 很小一部分知识,更加深入学习会使你养成一种良好编写单元测试的习惯,这是十分难得的一种好习惯,推荐去看官方文档,然后动手去测试一下,为你编写的每一个 Controller 方法进行测试,保证他们的可靠性。本章节所用代码可在下方码云地址中查看。

使用Mock测试的更多相关文章

  1. Python单元测试和Mock测试

    单元测试 测试可以保证你的代码在一系列给定条件下正常工作 测试允许人们确保对代码的改动不会破坏现有的功能 测试迫使人们在不寻常条件的情况下思考代码,这可能会揭示出逻辑错误 良好的测试要求模块化,解耦代 ...

  2. mock测试到底是什么?

    ​    ​经常听人说mock测试,究竟什么是mock测试呢?mock测试能解决什么问题?mock测试要如何做呢?今天为大家做简单介绍,之后会有详细的mock测试,感谢大家对测试梦工厂的持续关注. 概 ...

  3. mock测试框架Mockito

    无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访 ...

  4. Spring MVC如何测试Controller(使用springmvc mock测试)

    在springmvc中一般的测试用例都是测试service层,今天我来演示下如何使用springmvc mock直接测试controller层代码. 1.什么是mock测试? mock测试就是在测试过 ...

  5. mock测试

    看到群里有人说mock测试,究竟什么是mock测试呢?开始自己也没明白,查了下相关资料.还是很有必要了解哈:那么mock测试能解决什么问题?mock测试要如何做呢?今天为大家做简单介绍.mock测试就 ...

  6. Postman入门之Mock测试

    1.什么是Mock测试: mock测试就是在测试过程中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法. 2.添加要Mock测试的接口为example: 2.1点击r ...

  7. java的mock测试框架

    无论是敏捷开发.持续交付,还是测试驱动开发(TDD)都把单元测试作为实现的基石.随着这些先进的编程开发模式日益深入人心,单元测试如今显得越来越重要了.在敏捷开发.持续交付中要求单元测试一定要快(不能访 ...

  8. mock测试SpringMVC controller报错

    使用mock测试Controller时报错如下 java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig at org.spr ...

  9. 【转】MOCK测试

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

  10. RPC接口mock测试

    转载:http://blog.csdn.net/ronghuanye/article/details/71124127 1        简介 Dubbo目前的应用已经越来越广泛.或者基于Dubbo二 ...

随机推荐

  1. Linux 启动/关闭 oracle 数据库

    1.启动 1.1 启动监听 :lsnrctl start 1.2 启动数据库:sqlplus /nolog    conn /as sysdba(或者两句一起:sqlplus sys/ as sysd ...

  2. Dataworks批量刷数优化方案探讨

    Dataworks批量刷数优化方案探讨 在数据仓库的日常使用中,经常会有批量补数据,或者逻辑调整后批量重跑数据的场景. 批量刷数的实现方式,因调度工具差异而各有不同. Dataworks调度批量刷数局 ...

  3. Centos 7 成功安装 dosbox 解决 "error: expected primary-expression before ‘,’ token" 错误

    dosbox-0.74 bug 修复版下载: http://download.csdn.net/detail/yangbodong22011/9663271 注意:这篇博客解决了下面这个问题,如果你也 ...

  4. hudi clustering 数据聚集(一)

    概要 数据湖的业务场景主要包括对数据库.日志.文件的分析,而管理数据湖有两点比较重要:写入的吞吐量和查询性能,这里主要说明以下问题: 1.为了获得更好的写入吞吐量,通常把数据直接写入文件中,这种情况下 ...

  5. mysql批量修改某一列的值为另外的值

    sql语句 UPDATE tb_info SET org_id = 2170 WHERE org_id = 815

  6. 监控框架 - prometheus

    1.关于Prometheus Prometheus是一个根据应用的metrics来进行监控的开源工具.相信很多工程都在使用它来进行监控,有关详细介绍可以查看官网:https://prometheus. ...

  7. 关于使用idea工具debug时,断点颜色由红色变成灰色

    在使用断点调试的时候,发现断点由原来的红色变成灰色的,后来发现是由于错误操作将Debug断点t调试禁用了 ,只需要点击禁用按钮取消就可以了 

  8. ORACLE,mysql中替换like的函数

    数据库中存储了海量的数据,当查询时使用like,速度明显变慢.我在做项目时,发现使用内部函数INSTR,代替传统的LIKE方式查询,并且速度更快. INSTR()函数返回字符串中子字符串第一次出现的位 ...

  9. 暑假算法练习Day2

    第二天啦!大家一起冲冲冲!! 1004 成绩排名 (20 分) 读入 n(>0)名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式: 每个测试输入包含 1 个测试用 ...

  10. 来了!公开揭密团队成员开发鸿蒙 OpenHarmony 的完整过程(收获官方7000奖金和开发板等,1w字用心总结)

    背景 随着 OpenHarmony 组件开发大赛结果公布,我们的团队成员被告知获得了二等奖,在开心之余也想将我们这段时间宝贵的开发经验写下来与大家分享,当我们看到参赛通知的时候已经是 9 月中旬的时候 ...