业务代码写单元测试的最佳姿势是什么?

2021-05-16 22:57:22 +08:00
 XiLemon

最近看了极客时间的 [ 10x 程序员工作法] 和 [设计模式专栏] ,里面有一些关于单元测试的内容, 看完之后,感觉好像懂了,但是回头一看自己写出的代码,却不知道如何下手。

想请教一下大家,日常工作中是如何写单元测试的,团队的规范是怎样的,怎么迈出单元测试的第一步!!!

9964 次点击
所在节点    Java
59 条回复
lhx2008
2021-05-16 23:00:35 +08:00
面向对象设计,把代码分层好,这样底层就可以 mock 住,这样就可以开始跑单测了
Jooooooooo
2021-05-16 23:00:53 +08:00
和你说个秘密, 这些都是书上说的好听.
XiLemon
2021-05-16 23:03:37 +08:00
@lhx2008 现在的项目里代码分层比较乱,service dao 飞来飞去,有点难搞哇
@Jooooooooo 不会吧,老哥,我看设计模式专栏的例子,还挺贴切的。就是转到公司的项目,感觉无从下手
lhx2008
2021-05-16 23:07:59 +08:00
@XiLemon #3 如果是 SQL CURL,可以考虑直接上集成测试吧,或者后端改成用临时数据库( h2, sqlite )来本地跑,不用 mock 了,如果涉及到到调出到外部的 API 再考虑 mock
Jooooooooo
2021-05-16 23:19:00 +08:00
@XiLemon 还有诸如 DDD, RESTful 之类的东西你会发现都是说的好听, 实践几乎没有的.
fpure
2021-05-16 23:22:36 +08:00
@Jooooooooo 确实,实践这一套的成本不低
aragakiyuii
2021-05-16 23:25:01 +08:00
我感觉得先写出来能写单测的代码...然而现实情况是由于时间问题能跑就行
XiLemon
2021-05-16 23:40:50 +08:00
@lhx2008 谢谢
@Jooooooooo 0.0.. 没有实践过。。。
@fpure 不能光看成本呀,收益如何呢
@aragakiyuii 现实就是写的业务代码,对单测很不友好。假设时间够,我该怎么写出单测友好的代码呢,光看一些简单的例子,领悟不了 ─.─||
ClericPy
2021-05-17 00:27:52 +08:00
之前也强制自己尝试 TDD DDD 什么的, 后来发现自己抽象的不好是原罪... 不过单元测试一直写的比较完整, 所以至今没出过大问题, 而且每次上线前被测试拦住都有一种劫后余生的畅快
mxalbert1996
2021-05-17 00:37:52 +08:00
@lhx2008 事实上 mock 并不是一个很好的解决方案,如果可能的话应该尽量避免写出需要 mock 才能测试的代码。具体可以看这个:
https://android.googlesource.com/platform/frameworks/support/+/androidx-main/docs/do_not_mock.md
ccde8259
2021-05-17 00:49:21 +08:00
什么 TDD DDD 最后都要败给 DDL……
能上,能用,能赚钱才是王道。
单测首先 Mock 环境就够喝一壶。Mockito 还是 PowerMock 得引入。H2 和 RedisMock 都要折腾。还有 RPC 需要 Mock……
然后就是真正开始准备编码,单测里面你会发现自己代码根本没法单测……一个接口设计的不合理就要改接口来满足单测。具有上下文依赖的接口是不是要改显式注入?接口过于万能引起测试用例过多是不是需要拆分?代码覆盖率偏低是不是要调整?
坑太多收益也很一般。多数应用生命周期很短,过功能测试就上。用完就扔导致多数单测都是赔本买卖。
XiLemon
2021-05-17 01:10:26 +08:00
@ClericPy 希望能分享一下经验
@mxalbert1996 我理解也是,今天看了一下代码,一个方法,要 mock 四五个对象,完全没办法写单测嘛
hallDrawnel
2021-05-17 01:28:51 +08:00
单元测试要求在开始写代码的时候,就需要考虑可测试性,还得准备一堆基础设施才行,例如单元测试的时候日志系统和配置系统要能够更方便支持单元测试的场景,要比 mock 做得更方便才行,不能什么都靠 mock,至少基础设施要对单元测试友好。遗憾的是很多项目开始就没有考虑过,后期引入就代价很大。而且很多代码生命周期太短了,没啥测试的价值,引用个需求文档后期要改有个参考就行。
BeautifulSoap
2021-05-17 01:45:31 +08:00
单元测试最头痛的还是数据库怎么办
很多人都说 mock,但是我感觉实际上这么做对数据库来说并不是个好方法(坑一大堆)
所以一般业务代码测试我都是直接用实际的数据库来做的(主要针对 repository 层,java 似乎叫 dao ?),在每个测试开始前都清空下测试用数据库就行了

至于上层的测试,如 service 的测试里要不要 mock 掉 repository 接口之类的,我还不能得出明确的结论。可能 mock 掉比较好,不受下层实现的限制,但是有时候一些单元测试要 mock 的接口实在太多了,而且各种接口的依赖性非常复杂的话,光是 mock 都是个体力活,还不如直接用。
ericgui
2021-05-17 03:37:52 +08:00
业务变动比较大,怎么测?今天写了 2 个 test case,明天业务变了,这俩 test cast 就要删了,这不是浪费时间么
vemier
2021-05-17 08:50:02 +08:00
尽量使用集成测试代替多层的单元测试就好了,复杂的功能可以另外加单测。这样后期如果重构的话,测试用例完全不用改动,也少了很多意义不大的 Mock 。
bsg1992
2021-05-17 09:13:15 +08:00
业务代码很难进行单元测试的。
数据库没法进行测试,引入 InMemory DB 对数据库达不到测试的要求。
如果要介入数据库还得写插入和清库的代码。
第三方依赖也是一个问题。
到最后你会发现,写业务代码一个小时,单元测试得写上一天
witcherhope
2021-05-17 09:18:21 +08:00
如果团队没实行没规范,独狼很难做下去,团队有人推动,单测保证高覆盖率收益还是很大的
janxin
2021-05-17 09:18:23 +08:00
什么 TDD 还是 BDD 之流,最终还是落地到 ADD
leafre
2021-05-17 09:29:03 +08:00
楼上这些单元测试是什么都没弄清楚

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/777305

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX