单元测试相关:spring test、mockito、h2
背景
本文讨论单元测试,在单测中遇到的迷惑。单测中测一次就删除数据下次就没法再测怎么办,第三方的接口很不稳定我们要怎么测,整个业务规则这么多限制和要求怎么办? 你领导压缩工期没有足够单测的时间怎么办?
关于mockito和h2相关的,后续再发文,敬请不要期待,later is never~
啰嗦
先总结一波目前单测遇到的问题,比较杂,想到什么写什么,罗啰嗦
-
无spring容器启动的单元测试,基本没什么用,因为现在的project都是用spring的,你不注入bean根本就没法测
-
有spring容器启动的单测,我叫 spring test(你们是怎么称呼的?)
-
国内程序员做单测,很少用断言,基本上都是运行单测并打印结果,肉眼观察结果对不对。这是个习惯问题
-
国内领导很少给开发任务留单测的时间,有时候测试花的时间可能比开发还要多,但是很多领导没这样的意识,从而导致单测被草草执行,通常成为时间不足压缩的对象。所以追求覆盖率的单测常常流于形式或者应付(单测保证都难还要求覆盖率)。但是话说回来,写单测还是有好处的,静下心,静下心。。。
-
单测,很多人都是测service层的接口,而不是从Controller层开始测,从而可能导致有些入参判断逻辑没测到(特别是在Controller写重逻辑的)
-
单测,可以直接调用Controller方法进行测试,但是这种情况是接口的直接调用,所以对于@RequestParam 和 hibernate-validator(jsr303)这些校验,都测不到(因不触发检测),所以必须发起http请求测
-
发起http请求测,可以用spring带的MockMvc,这种情况jsr303的参数校验是可以被激活的,会测得全一点
-
对于一些接口,特别是第三方的接口,我们可以用mockito等框架进行mock测试。这类型的接口同样要么还在开发中未ready,要么是未部署或环境问题,或运行中响应慢等等因素可能会导致单测失败,推荐mock掉。
-
单测后,数据有可能被改变,我们怎么样回滚? 有些测试是有前置条件的,比如查某个数据,查不到时时接口无法继续,那我们怎么测试? 大家共用单测的数据库,你的数据是可能被同事删掉的
-
使用@Translational注解@Test方法,可以回滚数据,这样可以防止单测后数据改变
-
可以在单测 “查询接口” 的时候,先插入数据,这样每次查询时都存在
-
用内存数据库h2,我们换了思路,不操作实际的库,操作这个内存库
但是前提是这个内存数据库有这些表结构和数据
-
h2提供了在单测前执行sql脚本初始化所需表和数据的功能,这样就有表和数据了。(整理建表语句、insert语句、解决sql写法的差异是个耗时工作)
TIP: h2可以设置MODE是MYSQL、PostgreSQL等,有点设置方言的意思,即把h2当成你想要的类型的数据库,这样特殊写法的sql才能执行成功(例如mysql里可以用on duplidate,但h2里会报错,指定MODE=MYSQL后可以解决) `spring.datasource.url=jdbc:h2:mem:test;MODE=MYSQL` 但是这个MODE 不是指定了库的种类就完事,例如,即使MODE=PostgreSQL,执行本不该报错的`on conflict` 语句时还是报错。又如DDL建表,从Navicat导出来的,也不是不加修改就可执行成功,这也是麻烦点
-
还有一个办法,是通过jpa hibernate的反向工程生成表结构,这样就不需要整理表结构(美好的愿望)
通过jpa hibernate,在数据库表POJO,写上一定的注解,开启hibernate的反向工程,似乎能够解决。 本来项目是用Mybatis的,现在为了这个事情,需要添加jpa的注解 表是生成了,但是数据似乎还是需要插入,怎么插入,可以用Mybatis或jpa的方式插入,其实也还是很麻烦
-
-
总结
对于单测,总结几点
-
不要搞什么h2,不实用。整理sql脚本生成表并插入数据,麻烦,而且后期还要维护表变更等。又不是直接Navicat导出表结构和数据的sql就能用,还得整理。
-
也不要搞什么jpa反向工程生成表,且不说这种情况能不能顺利生成表,初始化数据还是得老实写,方便些可能还不如sql脚本导入
-
直接就使用共同的库进行单测,这些情况这么解决
-
删除数据:加上@Translational,回滚。或者你要测试删除,则自己先新增,再删除
-
某个业务接口需要数据先存在,但是保证不了数据不被同事删除:自己在测试中先新增,再查询
-
依赖第三方接口:用mockito
-
其他的业务依赖:具体问题具体解决
比如新增xxx,有业务要求xxx的name字段不能重复,我怎么保证单测时插入的数据不重复? 可以使用用随机名字,要是随机都重复了,那就认命。(你也可以较真,去数据库先查一把所有name,然后锁住表,再插入不重复的name)
-
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/135279.html