.NETテストプログラミング入門3
前回のテストコードは、シンプルを前提にすると、オブジェクト指向プログラミングでは限界に近いと思います。しかし現代的なプログラム言語には、もっとスマートな方法があります。それは、関数型言語の要素を取り入れる事です。
関数型プログラミングの考え方を取り入れると、いとも簡単にテストを行うための前提が減ります。
using System;
using System.IO;
class Tester
{
//関数(この場合はプロシージャ)を渡せばいい
public bool ConsoleOutCheck( string right, Action proc )
{
//出力先を変えてテストを行いやすくする
TextWriter tmp = Console.Out;
StringWriter writer = new StringWriter();
Console.SetOut( writer );
//テスト対象を実行
proc();
//出力設定を元に戻す
Console.SetOut( tmp );
////出力値をテスト
bool result = writer.ToString().Equals( right );
return result;
}
}
class Piyo
{
public void Greeting()
{
Console.WriteLine( "おはピヨ♪" );
}
}
class HelloWorld
{
public void FirstProgramming()
{
Console.WriteLine( "Hello World!" );
}
}
class Test
{
static void Main( string[] args )
{
//テストの準備
Tester tester = new Tester();
//Piyoクラスのテストを実行
Console.WriteLine( "これからPiyoテストを実行します。" );
Piyo piyo = new Piyo();
string right = "おはピヨ♪" + Environment.NewLine;
bool result = tester.ConsoleOutCheck(
right,
() => piyo.Greeting() );
string message = result == true ? "テスト成功" : "テスト失敗";
Console.WriteLine( message );
Console.WriteLine();
//HelloWorldクラスのテストを実行
Console.WriteLine( "これからHelloWorldテストを実行します。" );
HelloWorld hello = new HelloWorld();
right = "Hello World!" + Environment.NewLine;
result = tester.ConsoleOutCheck(
right,
() => hello.FirstProgramming() );
message = result == true ? "テスト成功" : "テスト失敗";
Console.WriteLine( message );
Console.WriteLine();
}
}
このテストの要件はあるコンソールへ文字列を出力するメソッドの正しさをチェックしたいという事です。ならばテストコードは、任意のメソッドが実行できればよいのであって、オブジェクトに拘る必要は何もありません。なお、このテストコードにおいて、Actionデリゲート引数が最後になっているのは、Funcデリゲート引数などのオーバーロード(多重定義)メソッドを増やす事が予測できるからです。正しい値を後にすると読み難いので、オーバーロードされると予測できるパラメータは最後にします。
このテストコードで完成と思った人も多いかと思います。ですが、これはまだ不完全なテストコードです。コンソールの性質を考慮すると十分とは言えません。まだ問題点があります。その問題点は・・・次回へ続く。