技术选型
UT框架:JUnit (4.12)Mock框架:Mockito (1.10.19)文件、类与方法命名规范
源文件目录src/main/java
UT文件目录
src/test/java
UT类命名规范
假设源类的全限定名为 com.yourcompany.api.Matching
源文件路径 src/main/java/com/yourcompany/api/Matching.javaUT文件路径 src/test/java/com/yourcompany/api/MatchingTest.java#注:UT类和源类在同一个package下有一个好处就是源类中的protected方法对UT类可见,即UT可以测试源类的protected方法,源类又可以保持封装性。
另外需要提醒的是:UT不对接口做测试,而是对具体实现做测试。比如:
对于接口文件:src/main/java/com/yourcompany/api/MatchingService.java假定对应的实现类文件为:src/main/java/com/yourcompany/api/MatchingServiceImpl.java那么 UT 的文件为 MatchingServiceImplTest.java,而不是 MatchingServiceTest.java:src/test/java/com/yourcompany/api/MatchingServiceImplTest.java
UT方法命名规范
比如源方法名为:matching()UT方法命名为:testMatching_SuccessWhenCurrentPriceBetweenBuyPriceAndSellPrice()testMatching_SuccessWhenCurrentPriceGreaterThanBuyPrice()testMatching_FailWheBuyPriceLessThanSellPrice()即:test"源方法名"_"后缀" (后缀用于描述同一方法的不同测试场景)
具体实践规范
所有public方法必须被单元测试覆盖
只测试public 和 proctected方法
注:虽然可以通过技术手段(例如java反射机制)来访问并测试private方法,但对于高效写单测来说这会带来一些技术负担,不是好的实践。
再说,private方法本来就不该有太复杂的逻辑。如果你说一些复杂逻辑应该对外隐藏细节,外部不需要理解这些细节,应该用private修饰,不给外部调用。
那么我说,你是有道理的。但private修饰之后,你自己都无法对这些复杂逻辑做单测了,所以采取折衷方式,用protected修饰,既能保持一定封装性–外部
package无法访问,又能写单测。(关于单测和私有方法可以参阅InfoQ的这篇文章《单元测试VS私有方法》)
文件,外部Service和数据库和其他中间件的存取都必须mock掉