VS2010 学习笔记 TDD (4) 重整代码(一)

我们都已经发现,前3节我们虽然创建了SimpleStack类,也实现了IsEmpty属性和Push方法,也通过了测试。但毫无疑问,这完全不合常理。那这节开始,我们要进入三部曲的重整代码阶段。所谓重整,就是将最简单能使测试通过的代码,加入必要的代码,以达到实际所需功能,同时也能让测试通过。

任务 1 – 将精力从让测试通过转移到完成功能上
  • 我们需要真正将一个对象推入到栈中,并实际改变了栈,即在推入对象后,栈应当保存这个对象,栈就应该不为空栈(IsEmpty等于false)。那怎么去测试呢?Push后验证IsEmpty 是否为false就行了:

[TestMethod]
public void ThenShouldBeAbleToPushAnItemOntoTheStack()
{
    var theStack = new SimpleStack();
    theStack.Push(1);

    Assert.IsFalse(theStack.IsEmpty);
}

  • 运行这个测试,应该不会通过。为什么失败呢?
    • 别忘了,我们之前为了让测试通过,只是简单将IsEmpty实现为只读的永远返回true的属性。现在就要考虑如何让IsEmpty按实际情况来返回真实的数值,也体现出Push方法带来的效果。
    • 测试驱动开发同时也被称为测试驱动设计 ,就是基于我们即将要看到的这些原因,我们正在定义开发的系统应当有什么行为和怎么去设计它,用重复方法来表现系统行为。
  • 打开SimpleStack类,我们坐下来思考一下这个类。栈应该可以提供储存某些状态的机制,特别是它现在储存何种条目的状态。 
  • 将条目储存在一个列表中,我们就可以检查列表的大小来确定栈的IsEmpty值。列表也提供了储存推入的条目的地方。

class SimpleStack
{
    ArrayList _items ;

    public bool IsEmpty
    {
        get { return _items.Count == 0; }
    }

    internal void Push(int p)
    {
        _items.Add(0);
    }
}

  • 注意ArrayList 类型未被识别,利用CTRL+. ,输入System.Collections 命名空间。
  • 运行所有的测试。还是失败!为什么?测试结果给出的原因是ArrayList未被初始化。
  • 添加默认的构造方法,并初始化列表

class SimpleStack
{
    ArrayList _items;

    public SimpleStack()
    {
        _items = new ArrayList();
    }

    …
}

  • 再次运行测试,这时候应该全部通过!(绿色)
  • 但问题来了,我们怎么知道Push方法存入正确的对象呢?就如我们上面的代码,Push方法只是将 (0)加入到列表中。
  • 因此,我们的测试方法就要继续做进一步的测试验证,同时也要添加新的功能(方法)。
  • 添加一个新的测试,使之可以验证推入一个对象后,能够拉出这个对象,并确保它就是我们刚刚推入的对象:

[TestMethod]
public void ThenShouldBeAbleToPushAndPopAnItemFromTheStack ()
{
    var theStack = new SimpleStack();
    theStack.Push(1);

    int poppedItem = theStack.Pop();

    Assert.AreEqual(1, poppedItem);
}

  • 再次提示Pop 方法不存在,我们使用Smart Tag帮忙创建新的方法,并利用Quick Search(CTRL+,) 定位到此方法
  • 注意VS已确定Pop方法需要返回一个值,并且知道返回值的类型,真牛!

internal int Pop()
{
    throw new NotImplementedException();
}

  • 运行测试方法,会失败并提示NotImplementedException 意外。我们添加代码使之可以通过测试:

internal int Pop()

{
    int value = (int) _items[0];
    _items.RemoveAt(0);

    return value;

}

  • 再次运行测试,还是失败。为什么呢?因为Assert使用AreEqual 方法来验证推入的数据和拉出的数据是否一样,结果在Push方法的实现代码中,我们错写了Add(0) 。回到Push方法,将代码改为:

internal void Push(int p)
{
    _items.Add(p );
}

  • 再运行测试,所有测试应该成功!

注意:我们现在不是深入讨论TDD的原理和规范上,也不是学习如何正确地实现一个栈类。
但是我们可以继续设计和建立SimpleStack类,比如思考Pop方法调用在空栈上会出现什么问题,还有如果尝试操作一个满栈的时候会出现什么情况等等。
为了完成这些设计问题,我们需要创建更多新的测试方式,完成更多的测试方法。
同时,我们也可能留意到这个类存在一个明显的bug,对于栈应该是先入后出(FILO),但Pop方法永远都是从开头拉出对象。那就要继续设计测试方法来确定Push进入的数据就是Pop出来的数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值