VS2005環境でのNAgile - はじめてのTDD (-.-)

今日はうちのチームのメンバーにはじめてTDDでコードを書いてもらった。
お題は月並みなStackのテスト。ただしジェネリックで。

BindlessStackのテストクラス

using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using StackStudy.Core;

namespace StackStudy.Tests
{
 [TestClass]
 public class BindlessStackTest
 {
  [TestMethod]
  public void 要素を含んでいないスタックのカウントは0であるべき()
  {
   BindlessStack<int> stack = new BindlessStack<int>();
   Assert.AreEqual<int>(0, stack.Count);
  }

  [TestMethod]
  public void 要素を1つプッシュしたスタックはカウントが1であるべき()
  {
   BindlessStack<int> stack = new BindlessStack<int>();
   stack.Push(1);
   Assert.AreEqual<int>(1, stack.Count);
  }

  [TestMethod]
  public void 要素を1つプッシュしたスタックをポップするとカウントは0であるべき()
  {
   BindlessStack<int> stack = new BindlessStack<int>();
   stack.Push(1);
   stack.Pop();
   Assert.AreEqual<int>(0, stack.Count);
  }

  [TestMethod]
  public void 要素を1つプッシュしたスタックをポップするとプッシュされた要素と同じであるべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   string pushed = "test";
   stack.Push(pushed);
   string popped = stack.Pop();
   Assert.AreEqual<string>(pushed, popped);
  }

  [TestMethod]
  public void 複数の要素をプッシュしたスタックからそれぞれをポップすると正しい順番で要素が削除されるべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   string pushed1 = "test1";
   string pushed2 = "test2";
   string pushed3 = "test3";
   stack.Push(pushed1);
   stack.Push(pushed2);
   stack.Push(pushed3);
   string popped = stack.Pop();
   Assert.AreEqual<string>(pushed3, popped);
   popped = stack.Pop();
   Assert.AreEqual<string>(pushed2, popped);
   popped = stack.Pop();
   Assert.AreEqual<string>(pushed1, popped);
  }

  [TestMethod]
  public void 要素を1つプッシュしたスタックからピークするとカウントは1であるべき()
  {
   BindlessStack<int> stack = new BindlessStack<int>();
   stack.Push(1);
   stack.Peek();
   Assert.AreEqual<int>(1, stack.Count);
  }

  [TestMethod]
  public void 要素を1つプッシュしたスタックからピークするとプッシュされた要素と同じであるべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   string pushed = "Test";
   stack.Push(pushed);
   string peeked = stack.Peek();
   Assert.AreEqual<string>(pushed, peeked);
  }

  [TestMethod]
  public void 要素を1つプッシュしたスタックからピークを繰り返すとプッシュされた要素と同じであるべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   string pushed = "Test";
   stack.Push(pushed);

   for (int i = 0; i < 10; i++)
   {
    string peeked = stack.Peek();
    Assert.AreEqual<string>(pushed, peeked);
   }
  }

  [TestMethod]
  public void 複数の要素をプッシュしたスタックでピークで返された要素は最後にプッシュした要素と同じであるべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   string pushed1 = "Test1";
   string pushed2 = "Test2";
   string pushed3 = "Test3";
   stack.Push(pushed1);
   stack.Push(pushed2);
   stack.Push(pushed3);
   Assert.AreEqual<string>(pushed3, stack.Peek());
  }

  [TestMethod]
  [ExpectedException(typeof(InvalidOperationException))]
  public void 要素を含んでいないスタックをポップすると例外が発生すべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   stack.Pop();
  }

  [TestMethod]
  [ExpectedException(typeof(InvalidOperationException))]
  public void 要素を含んでいないスタックをピークすると例外が発生すべき()
  {
   BindlessStack<int> stack = new BindlessStack<int>();
   stack.Peek();
  }

  [TestMethod]
  public void NULLをプッシュしたスタックはカウントは1であるべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   stack.Push(null);
   Assert.AreEqual<int>(1, stack.Count);
  }

  [TestMethod]
  public void NULLをプッシュしたスタックをポップするとNULLが返されるべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   stack.Push(null);
   Assert.IsNull(stack.Pop());
  }

  [TestMethod]
  public void NULLをプッシュしたスタックをピークするとNULLが返されるべき()
  {
   BindlessStack<string> stack = new BindlessStack<string>();
   stack.Push(null);
   Assert.IsNull(stack.Peek());
  }
 }
}

BindlessStackの実装クラス

using System;
using System.Collections.Generic;
using System.Text;

namespace StackStudy.Core
{
 public class BindlessStack<T>
 {
  private List<T> elements_ = new List<T>();

  public BindlessStack()
  {}

  public int Count
  {
   get { return elements_.Count; }
  }

  public void Push(T element)
  {
   elements_.Insert(0, element);
  }

  public T Pop()
  {
   T peeked = Peek();
   elements_.RemoveAt(0);

   return peeked ;
  }

  public T Peek()
  {
   if (Count == 0)
    throw new InvalidOperationException("要素が空です。");

   return elements_[0];
  }
 }
}