文档计划(暂定)
文档名称 计划完成时间 完成状态 第一篇 - 需求分析 2011-7-28
第五篇 - JDT生成单元测试
2011-7-31
寄语
今天给其他同事做了单元测试脚手架的分享,但是效果感觉不佳,因为我只是懵懵懂懂做好了,而后模模糊糊地重构优化了,但是怎样把这些经验、技术很好的表达出来,我确实还非常欠缺想法和实战经验,所以开始编写这几篇连载,想设法清晰地表达我开发这个插件的过程中遇到的各种各样的问题、以及解决思路。
前言
Boss常说:工具能做的事情,不要让工程师来做,尽量交给工具。而工程师应该将他们的思维和智慧用于更具创造力的地方。
什么是单元测试脚手架
首先,介绍一下什么是单元测试脚手架,意思是:你拿到一段需要做单元测试的代码,扔给这个插件,它会根据代码的一些特点,帮忙生成一些有规律的代码骨架,而后骨架里要放些什么馅儿之类的,就由开发者自己编写了。
还是举个例子吧。
对了,本文假定你也经常用某些框架来编写单元测试代码,最好就是跟笔者一样用的是JTester框架,如果实在不是,只要用过JMockit或者类似的就成。
有这样一个业务类代码:
public class DemoService {
BizSerivce bizSvr;
DataService dtSvr;
......
public int doBiz() {
return dtSvr.update(bizSvr.findById(1L));
}
}
在单元测试的概念中,定义bizSvr, dtSvr这样的成员变量为外部依赖,我们并不关注它们的实现,所以我们在编写单元测试代码的时候,通常会把它们mock掉。
在JTester中,通常会这样写DemoService的单元测试:
public class DemoServiceTest extends JTester {
@SpringBeanByName
DemoService demoService;
@SpringBeanFor
@Mocked
BizSerivce bizSvr;
@SpringBeanFor
@Mocked
DataService dtSvr;
@Test
public void test_doBiz() {
new Expectations(){
{
bizSvr.findById(anyLong);
result = ......;
dtSvr.update();
result = 1;
}
};
want.number(demoService.doBiz()).isEqualTo(1);
}
}
脚手架可以做的事情
细心观察这段代码,不难发现,这个单元测试类DemoServiceTest中,成员变量的声明、测试方法test_doBiz的声明、测试方法内的Expectations的创建代码中的mock代码,都是有规律可循的。
脚手架不能做的事情
我们所无法帮助编码者判断的是,这些mock代码需要返回什么值,它的入参可能是什么值,最终want.number()断言里会期望怎样的返回值。
需求明确了
这样脚手架的需求便明确了——为一个业务方法生成单元测试类,它当中会包括被测业务类、外部依赖类的声明、单元测试方法的声明以及方法调用的mock信息。