单元测试的过渡解决方案

要想将已有的代码进行单元测试,是一件不容易的事情。
在最近的单元测试编写过程中,我发现以前写的那些代码,有很大一部分是不具备单元测试的。更然我头疼的是,要想在那些代码中引入单元测试,紧接着的不是思考如何写单元测试,而是思考如何重构代码,使其可以被单元测试。但是完成对已有系统的重构,哪里是一两天就可以完成的,特别是那种业务逻辑密集的模块,更是需要花一整块不间断的时间,使你想花零星的时间来进行代码重构成为不可能。

所以,就应该有一种单元测试的过度方案。

在看针对单元测试的代码设计的讨论中,有人提到这样一种方案,我对这种方案十分赞赏。现在有下面这段很难单元测试的代码:
public class B
{
    ......
    public void ResObject GetRes(long resId)
    {
    ....
    }
}
public class A
{
    public void DoSomething(long resId)//需要被单元测试的方法
    {
       ......
       if(CheckAvailability(resId))//检查可用性
       {
          .....//包含了希望测试的代码逻辑
       }
    }
    private bool CheckAvailability(long resId)
    {
       ......//检查可用性
       B b = new B();
       ResObj resObj = b.GetRes(resid);
       .....
       return true;
    }
}
CheckAvailability被声明在类A中,如果要测试DoSomething,那么CheckAvailability也会被考虑到。但是由于 CheckAvailability中使用了对象b,而b是一个使用了数据库资源的对象,所以在测试中,我们要Mock b。也就是说,在测试A.DoSomething的时候,我们除了要准备输入数据resId之外,还有准备b.GetRes的返回对象,更加值得我们注意的是,数据resId 和准备的Mock数据resObj不是互不相干的,它们之间存在者逻辑上的关联。但是现实中的代码有我举的例子那么简单吗?没有。面对这样的代码,要对其进行单元测试,其难度不亚于编写那段代码。

一边是重构代码,需要比较长的周期,项目进度不允许;一边是系统中要引入单元测试,以保证代码质量的紧迫性。我们只能去寻找第三条道路。

其实很简单,说破了谁都知道。用虚方法:将CheckAvailability声明为virtual。
protected virtual bool CheckAvailability(long resId)
{
    .....//检查可用性
       B b = new B();
       ResObj resObj = b.GetRes(resid);
       .....
       return true;
}

然后声明一个测试类TestA继承于class A
public class TestA : A
{
    protected override bool CheckAvailability(long resId) { return true;}
}
那么测试代码为:
long resId = 2031;//只需要准备一个数据
TestA testA = new TestA();
testA.DoSomething(resId);

我承认这种方法具有很大的争议,但是作为一种过度的方法(所谓过度用的方法就是以后要被抛弃的方法),是值得使用的。


 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明天好,会的

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值