场景

单元测试是个让人很纠结的东东,dealline 催的很紧,不想写单测,但当项目复杂到一定程度需要重构时,返现没有单测,不敢随便改代码,生怕”敲一锤子,倒一大片“,但此时再补,已经有点晚了。磨刀不误砍柴功,这会偷的懒后面总要跟你算账的,所以还乖乖写吧。

单测目的

这个很重要,不清楚目的,就不知道接下来该怎么做。这样也行,那样好像也可以,埋头写一大片,很快就没了兴趣,而且还会很烦写单测。常见 web 服务大都是 controller、service、repository 三层架构。每一层都有各自的任务,基于此单测的目的也就不同。

  • repository 层主要负责数据的持久化,它里面除了读和写,其他的逻辑越少越好。所以该层单测要连上数据库,将数据真正的写入并且读出,从而确认该数据持久化,以及各种查找功能正确。推荐持久化层单测内嵌 H2 数据库,它是基于内存的,不受物理机限制,而且各个单测 case 之间互无影响。
  • service 层负责处理业务逻辑,很复杂的项目往往也就是复杂在这一层了,这层肯定会依赖该项目的 repository 层,还可能会依赖 Redis、kafka、mq、httpClinet 等第三方的东西。每次单测都调用第三方,哪有那么听话的第三方,每次都能正确返回结果。这层单测怎么写?把 service 层依赖的 repository 和 第三方的东西都 mock 出来,并 when 他们对应的方法,按照测试需求控制其方法返回值,从而控制 service 层的方法中代码的走向,确认自己写的逻辑是没问题的。在这一层中,一个方法往往需要好几个测试 case,一个正例,若干的异常情况。
  • controller 层负责和前端交互,接收请求、校验参数、返回处理结果。最理想的单测肯定是模拟出生产环境下前端请求的执行。这是可以办到的。

三层单测有各自的目的,而且不依赖于其余两层,如果真依赖了,那就使用 mock,控制返回值。从而实现“隔离”,本层单测只需要实现本层的目的,其余的都是不需要知道的。

controller 层单测

mockMVC 可以实现在单测中模拟生产环境中前端请求的执行逻辑。

Controller:

@RestController
@RequestMapping("/trains")
public class TrainController {private TrainService trainService;@Autowiredpublic TrainController(TrainService trainService) {this.trainService = trainService;}@PostMapping("")public void create(@RequestBody @Validated ModelTrainsAddDTO req) {TrainEntity entity = new TrainEntity();BeanUtils.copyProperties(req, entity);trainService.create(entity);}
}@Data
@NoArgsConstructor
@AllArgsConstructor
public class ModelTrainsAddDTO {@NotBlankprivate String name;private String modelType;
}

单元测试

@WebMvcTest(TrainController.class)
class TrainControllerTest {@MockBeanprivate TrainService trainService;@Autowiredprivate MockMvc mockMvc;@BeforeEachvoid setUp() {RestAssuredMockMvc.mockMvc(mockMvc);}@Testvoid should_200_if_create_train_succeed() {ModelTrainsAddDTO param = new ModelTrainsAddDTO("name", "model-type", "trian-fileds", "evail-files", "param");given().contentType(ContentType.JSON).body(param).when().post("/trains").prettyPeek().then().statusCode(200);verify(trainService).create(any());}// 注解校验没通过,直接抛异常。@Testvoid should_500_if_name_is_null_when_create_train() {ModelTrainsAddDTO param = new ModelTrainsAddDTO(null, "model-type", "trian-fileds", "evail-files", "param");given().contentType(ContentType.JSON).body(param).when().post("/trains").prettyPeek().then().statusCode(500);}
}

RestAssuredMockMvc

RestAssuredMockMvc 详细使用方法在这里,需要科学上网。它采用熟悉的 given-when-then 的场景格式定义测试写法,里面有段这样的描述:

given() — specifies the HTTP request details
when() — specifies the HTTP verb as well as the route
then() — validates the HTTP response

当然也还有别的写法,比如:mockMvc.perform()

依赖

<dependency><groupId>io.rest-assured</groupId><artifactId>spring-mock-mvc</artifactId><version>4.5.1</version><scope>test</scope>
</dependency>

基于 mockMvc 的 Controller 层单元测试相关推荐

  1. SpringBoot使用MockMvc对Controller层进行单元测试

    Mockito是GitHub上使用最广泛的Mocking框架.它提供简洁的API来测试.Mockito简单易学.可读性强.验证语法简洁. [示例]使用Mockito框架,对Controller层进行单 ...

  2. 基于MariaDB4j实现持久层单元测试

    1. MariaDB4j是什么 MariaDB4j的官网对MariaDB4j的定位为: MariaDB4j is a Java (!) "launcher" for MariaDB ...

  3. SpringBoot—单元测试模板(controller层和service层)

    关注微信公众号:CodingTechWork,一起学习进步. 介绍 概述   在开发过程中,我们经常会一股脑的写各种业务逻辑,经常等全部大功告成的时候,打个jar包放环境里跑跑看看能不能通,殊不知在各 ...

  4. Spring Boot从Controller层进行单元测试

    单元测试是程序员对代码的自测,一般公司都会严格要求单元测试,这是对自己代码的负责,也是对代码的敬畏. 一般单元测试都是测试Service层,下面我将演示从Controller层进行单元测试. 无参Co ...

  5. 基于JavaSDK实现微信支付,springboot封装签名过程,直接调用controller层实现调起微信支付接口

    微信小程序实现微信支付需要繁杂的过程,各种接口调来调去,对于小白来说是一个比较复杂的过程.下方 开源项目 是对微信 javaSDK 的进一步封装.主要对service层和controller层进行了封 ...

  6. Spring Boot开发基于三层架构设计:Dao层、Service层、Controller层

    三层架构设计:基于Spring Boot开发要使用三层架构: 数据访问层(Dao).业务逻辑层(Service).控制层(Control-ler) (1)数据访问层(Dao):Dao层是最底层的设计, ...

  7. 实战SSM_O2O商铺_19【商铺编辑】Controller层开发

    文章目录 概述 ShopController ShopController#getShopInfoById方法 getShopInfoById 测试 ShopController#modifyShop ...

  8. 实战SSM_O2O商铺_15【商铺注册】View层+Controller层之图片上传

    文章目录 概述 Maven依赖 文件上传解析器bean的配置 页面 shopoperation.html增加上传组件 shopoperation.js Controller层 Github地址 概述 ...

  9. 实战SSM_O2O商铺_11【商铺注册】Controller层的实现

    文章目录 概述 结构 Maven依赖 封装工具类HttPServletRequestUtil Controller控制层编写 Service层的改造 单元测试 Github地址 概述 实战SSM_O2 ...

最新文章

  1. 轮播图js怎么设置图片自适应大小
  2. Java字符串常用操作
  3. 正则表达式_月隐学python第20课
  4. java statement 动态参数_java_web学习(九) PreparedStatement动态参数的引入
  5. WPF Path.Data 后台代码赋值
  6. android开发 修改标题栏背景_Android哆啦A梦调试工具体验
  7. 提升工作效率的优秀工具收藏
  8. 给model模型传数组参数
  9. 制图综合:河流水系提取简化
  10. 计算机电源管理设置,怎么修改电脑中设置的显卡电源管理模式
  11. 移动oa咋显示无法连接服务器,移动oa办公系统管理维护技巧:让本地连接不再受限的方法...
  12. 一加手机怎么root权限_一加5手机怎样Root,如何获取Root权限?
  13. 2014年 IT 行业校招待遇
  14. 高德地图报错USERKEY_PLAT_NOMATCH解决办法 + 通过经纬度获取当前位置
  15. 计算机图形学 | 实验四:绘制一个球体
  16. vue-微信小程序-自定义计时器-答题倒计时
  17. RMA退货流程解决方案
  18. android之使用QQ互联实现qq账号登录App
  19. 财务会计基础与报表的管理解读
  20. H3C--多区域OSPF配置实践

热门文章

  1. 类office2007工具栏
  2. 【Linux】万兆网卡82599驱动安装
  3. uniapp文字不显示
  4. 前端 element plus Popover气泡卡片 中再套个气泡卡片 点击第二个气泡框的时候第一个气泡框不会消失
  5. 2020京东618叠蛋糕脚本
  6. SCI文章投稿状态一览
  7. 全国计算机等级考试二级教程c语言程序设计考试大纲,全国计算机等级考试二级C语言程序设计考试大纲.docx...
  8. flash读取xml简明实例教程
  9. 智方3000系快餐店管理系统 手机软件下载
  10. ppt最全的网站,你想要的应有尽有,模板素材图片都包含在内!