初心者のためのC#プログラミング本格入門96 - 実装を意識しないテストを行おう
前回述べた「分けて考える」をより具体的に言うと、実装を意識してテストを作らない事を意味します。自分が行った実装を意識すると、どうしても先入観が生じ、間違ったテストを作ってしまう恐れがあります。先入観が入らないようにするには、やりたい事をそのままテストして実装しましょう。
改めて今行おうとしている事を考えると、自分のオブジェクトをforeach対応にする事です。それをテストで表現します。
class SimpleListTest : Test
{
private SimpleList target;
public override void ExecuteAllTest()
{
this.OneElementAdd();
this.CurrentTest();
this.AddElementCheck();
this.ForeEachTest();
}
//foreachを模倣する
private void ForeEachTest()
{
//準備
base.Execute();
this.target = new SimpleList();
for ( int i = 0 ; i < 10 ; ++i ) {
this.target.Add( i );
}
//1 ~ 9 の数値が格納されているはず
int x = 0;
System.Text.StringBuilder error =
new System.Text.StringBuilder();
do {
if ( this.target.Current != x ) {
string message = "予期せぬ値が返されました。" +
"予想値:" + x +
" 返された値" + this.target.Current +
System.Environment.NewLine;
error.Append( message );
}
++x;
} while ( this.target.MoveNext() );
if ( error.Length != 0 ) {
base.Error( error.ToString() );
}
}
foreachを直接使ってもよいのですが、それだとIEnumerableとIEnumeratorの働きが分かりません。そこで、foreachに近いプログラムにしました。テストをパスするには、次の様な実装にします。
//関係のあるプログラムだけ掲載しています
class SimpleList :
System.Collections.Generic.IEnumerable<int>,
System.Collections.Generic.IEnumerator<int>
{
private int readIndex; //読み取り位置
public System.Collections.Generic.IEnumerator<int> GetEnumerator()
{
return ( System.Collections.Generic.IEnumerator<int> ) this;
}
System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
{
return ( System.Collections.IEnumerator ) this;
}
public int Current
{
get { return this.data[ this.readIndex ]; }
}
object System.Collections.IEnumerator.Current
{
get { return this.data[ this.readIndex ]; }
}
public bool MoveNext()
{
++this.readIndex;
return this.data.Length > this.readIndex;
}
public void Reset()
{
this.readIndex = 0;
}
//保持しているリソースを解放
public void Dispose()
{
this.data = null;
}
}
まだまだ粗い実装ですが、ひとまずこれでパスを通過できます。これでひとまず、foreachループも使用できるようになります。
public void ForeEach()
{
this.target = new SimpleList();
foreach ( int value in this.target ) {
System.Console.WriteLine( value );
}
}
ただし、これは完全な実装ではありません。次回へ続く...