惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

P
Proofpoint News Feed
V
V2EX
博客园_首页
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Recent Announcements
Recent Announcements
博客园 - 司徒正美
Microsoft Security Blog
Microsoft Security Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Latest news
Latest news
Vercel News
Vercel News
The Register - Security
The Register - Security
T
The Exploit Database - CXSecurity.com
S
Schneier on Security
N
Netflix TechBlog - Medium
WordPress大学
WordPress大学
小众软件
小众软件
L
Lohrmann on Cybersecurity
GbyAI
GbyAI
P
Privacy & Cybersecurity Law Blog
T
Tor Project blog
AWS News Blog
AWS News Blog
美团技术团队
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
K
Kaspersky official blog
B
Blog RSS Feed
G
Google Developers Blog
量子位
大猫的无限游戏
大猫的无限游戏
Google DeepMind News
Google DeepMind News
Scott Helme
Scott Helme
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
I
Intezer
雷峰网
雷峰网
Martin Fowler
Martin Fowler
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Blog — PlanetScale
Blog — PlanetScale
IT之家
IT之家
F
Full Disclosure
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - 【当耐特】
The Hacker News
The Hacker News
U
Unit 42
S
SegmentFault 最新的问题
I
InfoQ
aimingoo的专栏
aimingoo的专栏
Y
Y Combinator Blog
宝玉的分享
宝玉的分享
罗磊的独立博客
Spread Privacy
Spread Privacy
C
CERT Recently Published Vulnerability Notes

博客园 - 李学斌

服务治理咋这么难?我想得换个治法了。 百度大会见解 李学斌:论复杂系统中的应用间协作V3 maven spring profile 协同 大视角、大方向、大问题、大架构:(结局)解决问题的出发点 大视角、大方向、大问题、大架构:(二)应用的相关问题 大视角、大方向、大问题、大架构:(一)信息时代下的管理 信息时代下,如何看待技术与理论 狼的架构暗示 狼群的架构暗示 基因与架构 由“I”到“T” 产品的臃肿过程 我们是在开发产品还是项目? 未来电子商务,未来的超市 创业期的软件开发管理(二) 创业期的软件开发管理(一) 平台架构--用户系统 平台架构——体系结构
写单元测试,我不认为是件容易的事
李学斌 · 2022-01-08 · via 博客园 - 李学斌

这是一个40多岁还在编码的老程序员对单元测试的理解和实践。里面没有废话,希望每句话能说到你心坎里。

原则:只测自己

自己的含义:方法边界内的主体逻辑。一切下游方法、框架依赖、外部IO等都不是自己。如spring、 外部数据库都视为外部逻辑。

这一原则的动机

便于定位

每个方法有自己独立的单元测试,这有利于IDE在单元测试与逻辑代码间跳跃,便于定位,并降低代码结构调整的影响范围。

不重复,降低复杂度

因每个方法有自己的单元测试,所以当前测试不要涵盖下游方法的功能测试。以避免逻辑改动造成不必要的影响范围扩大。

实践与建议

要想单元测试更易于维护,良好的设计是前提

分层开发

开发也是可以分层的,先进行框架开发后进行具体开发。如先定义好所有的接口和要传递的数据,并组织好控制层,然后测试和具体开发便可同时展开。这样便可提前发现结构性问题,提前对设计进行验证,减少后期结构性调整对单元测试的影响。

单一职责

尽量应用单一职责设计模式,使逻辑模块化,并使用老板原则将这些模块串起来。这对于类的内部实现尤其重要,因为这会影响单元测试的覆盖能力。

只有这样每个方法的逻辑才能简单,对应的单元测试自然便于维护。作为老板的控制类或方法不必苛求单元测试,可酌情选择是否单元测试,因为控制是少数派,且实质逻辑已经被分摊到模块中。

逻辑与外部IO分离

这是单一职责的延申,数据的加载、处理与输出是可以作为独立的三个职责的。其中数据的加载和输出往往与外部环境依赖有关,本身的测试意义不大,即便测试也不能到处运行,且测试运行效率低下。

所以我们需要将IO逻辑从处理逻辑中剥离,并放到外层的控制逻辑中去并用mock来解决。这样没有外部依赖的处理逻辑——核心,将得到简化,从而单元测试得到简化。

如果中间实在需要外部IO可考虑在IO处进行逻辑拆分,这样拆分后的子逻辑中就没有了IO依赖,从而得到简化。

到处运行

有时候单元测试是脱离不了环境的,如我们想验证一下 SQL 的正确性。此时建议在单元测试上应用 @Disabled 注解,以便在 mvn test 中忽略这些测试,从而保证测试可以到处运行。

@Autowired

请尽量避免对框架的依赖,如 spring 的 @Autowired 注入机制,这会巨幅增加单元测试的构建难度,巨幅增加单元测试的耗时,因为这会对 mock 对象的注入造成困难。

建议,使用构造注入代替属性注入,这样就可以摆脱对 spring 的依赖。