代码改变世界

测试驱动开发实践-重构篇

2009-06-18 16:16  shaofeng  阅读(2152)  评论(4编辑  收藏  举报
前一篇文章 测试驱动开发实践-入门篇 我们我们讲了一些基本的测试驱动开发流程:
1。写单元测试使他亮红灯
2。写代码使测试变成绿灯

3。重构代码

接下来我们需要开始重构了,大家有可能会问,为什么需要重构,什么时候开始重构。
对与为什么需要重构,其实就是为了使代码结构清晰,去除一些重复的代码,比如我们执行sql语句操作,我们起初这样写

Code

 

我们发现这里除了sql语句不一样之外,其他都是一样的,那我们就可以这样重构

Code

 

这样重构完之后,代码是不是清晰了很多呢?

那什么时候又开始重构呢,我们在觉得代码重复性太大了,层次结构混乱了等等(就是传说中的有坏味道的代码)都可以重构,有测试在,还需要怕代码改错吗?
接下来我们就接着前一篇文章的用例按照 设计模式原则进行重构(单一职责原则,接口隔离原则,依赖倒置原则等)
那么我们回头看一下这个登陆的方法里,包含了验证和数据操作的代码,根据单一职责原则,我们需要把他们放在不同的类中,就有了如下代码

1public interface IEmployeeService
2{
3    bool Login(string loginName, string password);
4    bool ValidateLoginName(string loginName);
5}
在上面代码中我们定义一个服务层接口,又把验证单独拿出来做了一个方法

下面是对服务层的实现

Code

 上面服务层我们可以看出,我们是调用了数据层接口的实现,而不是直接调用数据层的操作,这样的使服务层和数据层的关系进行解偶,服务层不是直接依赖于数据层,而是依赖于数据层接口,
这样有什么好处呢?
比如我们现在数据层的实现是和sqlserver进行交互的,下次要与xml进行交互了,那怎么办呢,那我们只要实现一个与xml数据交互的数据层就可以了,其他代码也就不用修改了。
其实模式就是为了 变化 而准备的,假如项目真要交付了,什么事都没有了,我们还搞什么模式呢,你觉得呢?
这里有点跑题了,接下来我们再回到主题,数据接口的定义如下

1public interface IEmployeeDataAccess
2{
3    int GetCount(string loginName, string password);
4}

 数据层我这里就形式一下了

Code

 最后我们还需要修改我们的测试用例,使他继续运行通过,最后的测试用例如下:

 

Code

 

 这里重构就到这里了,这里服务层测试使用到了moq的mock框架可以在 http://code.google.com/p/moq 下到,所以这里用了mock模拟数据层进行了测试,这个框架对于分层开发测试非常好,
在数据层没有写完的时候,我们就可以模拟数据层提供数据,直接对服务层进行测试。