在写代码的同时编写单元测试,可以理清逻辑,降低类/方法间的耦合,提高可读性,减少代码异常的出现。
在没有单元测试之前,有时迭代一个方法,排查一个bug,微服务系统要跑起多个服务。从入口链路一步步debug下去,获取数据运行方法。耗时耗力。单元测试往往可以拿之前mock的数据迅速写新的测试。快速解决问题。
BeforeEach
好的测试代码要兼具好代码的属性,最基本的要求就是消除重复。初始化代码反复在写的话可以放在@BeforeEach 进行定义的方法中
@BeforeEach
void setUp() {
...
}
Assert
断言,说白了就是拿执行的结果和预期的结果进行比较。是单元测试不可或缺的一部分。社区中有大量的第三方断言程序库,比如,Hamcrest、AssertJ、Truth。选择合适自己的即可。
Mock 框架提供的一种断言:verify。verify 的作用就是验证一个函数有没有得到调用。在某些测试里面,函数既没有返回值,也不会抛出异常。比如拿保存一个对象来说,我们唯一能够判断保存动作是否正确执行的办法,就是利用 verify 去验证保存的函数是否得到调用,就像下面这样。
verify(repository).save(obj);
一段旅程(A-TRIP)
看看如何衡量一个测试有没有做好?有人把好测试的特点总结成一个说法:A-TRIP。这其实是五个单词的缩写,分别是:
- Automatic,自动化;
- Thorough,全面的;
- Repeatable,可重复的;
- Independent,独立的;
-
Professional,专业的。
Automatic,可以借助Jenkins实现部署代码时自动化监测
Thorough,在开始编写单元测试时没必要面面俱到,那样耗费太多精力。等代码编写完毕,借用覆盖率工具完善单元测试即可
Repeatable:对于代码中涉及到外部资源,包括文件、数据库、中间件、第三方服务等等,也要保证单元测试的可重复性
Independent:测试和测试之间不应该有任何依赖。
Professional:测试代码也是代码,也要按照代码的标准去维护。这就意味着你的测试代码也要写得清晰,比如良好的命名、把函数写小、要重构甚至要抽象出测试的基础库、测试的模式。
可测试性
编写可测试的代码,最简单的回答就是让自己的代码符合软件设计原则
1,不要在组件内部去创建对象,它会产生耦合,可以考虑从构造函数把它作为参数传进来,或依赖注入的方式
2,不要编写 static 方法。由于不可控,会加大测试难度,除非编写一些基础库(比如字符串处理等)
3,不要编写全局状态和Singleton 模式。理由同上,如果你的系统中有全局状态,那就会造成代码之间彼此的依赖:一段代码改了状态,另一端代码因为要使用这个状态而崩溃。
网友评论