单元测试
在Java中单元测试指代码单元的测试用例,代码单元指类中的方法。单元测试是用以保证代码的逻辑正确性,测试用例越全则代码越稳定,可以保证重构时代码的正确性。一般情况下,建议先写单元测试再写具体代码,因为如果写完代码再设计单元测试则会受先入为主的影响,倾向于测试已完成代码的正确性,易于忽略边际情况。实际操作便是在编写类时首先考虑类的职责,即类用来干什么,首先设计好类接口,然后根据接口进行测试的编写,测试设计完成后再进行实际代码的编写,最后一步则是验证,循环往复直至所有测试通过。
单元测试为重构时提供了极大的便利,因为单元测试为代码的修改提供了结果的保证。如果重构失败,则单元测试不会通过。它保证了代码修改的信心,因为机器是不会骗人的。只要单元测试能够通过则代表重构是没有问题的。在没有单元测试的项目,我们要进行重构则会变得十分小心翼翼。我们会害怕影响其他功能,因为一个功能的变更常常会牵扯到其他功能,这样要验证重构的就需要验证完整的流程,这极大的增加了软件维护成本。而且在开发过程中也可以提高开发效率,因为验证代码的改动时只需运行部分代码,而不必编译整个项目。还有一点就是可以提高项目的代码质量,为了编写单元测试,我们不得不写好代码,而写好了代码则更利于单元测试,这其实是一个相互促进的过程。从长远来看,编写单元测试绝对是明智之举。
单一职责原则
单元测试中最重要的便是代码单元的划分,良好的职责分配更利于单元测试的进行。单一职责原则便是用于指导代码功能的划分,它保证代码结构的清晰,降低类的复杂度,为编写单元测试提供了极大的便利。
单一职责原则(Single responsibility principle)规定每个类都应该有一个单一的功能,并且该功能应该由这个类完全封装起来。遵循单一职责原的优点有:
- 可以降低类的复杂度,一个类只负责一项职责,其逻辑肯定要比负责多项职责简单的多;
- 提高类的可读性,提高系统的可维护性;
- 变更引起的风险降低,变更是必然的,如果单一职责原则遵守的好,当修改一个功能时,可以显著降低对其他功能的影响。
单一职责原则作为指导性原则在平时工作时应尽量遵循,特别是在进行功能设计的时候。但也应该应学会灵活变通,当代码逻辑十分简单的时候,暂时违背原则也并非不可,生搬硬套只会导致类的冗余。
私有方法或者保护方法是否需要单元测试?
其实这个问题可以引申为那些代码需要进行单元测试,我认为需要尽可能的覆盖单元测试,这样可以大程度保证代码的正确性,减少bug的数量。为了更方便的进行私有方法或者保护方法的单元测试,单抽成类是最好的办法。这样可以降低单个类的逻辑复杂度,逻辑更加清晰更利于单元测试。
为什么要多用组合少用继承?
在实际开发中大家都在提倡开发过程中要尽量使用组合少用继承,一直对这个不是非常理解,直到现在接触单元测试才有所领悟。因为使用继承类的行为就有可能受父类影响,如果要对子类进行单元测试则意味着同时需要对父类进行单元测试保证逻辑的正确性,这样显然不利于进行单元测试,单元测试应该是非常细粒度的,只是单个类的测试。