ASP.NET環境における単体テスト
ASP.NET Webアプリケーションを作成していると、ASP.NET特有の環境に依存しながら動作するメソッドがいくつもできてしまいます。例えば、リクエスト情報やセッション情報を必要としたり、Webアプリケーションの仮想パスと物理パスを変換して動作するような処理などが該当します。昨今は、従来のASP.NET Webアプリケーションの作り方ではテストがしにくいということを理由の1つに挙げ、ASP.NET MVCという新しい方法が提供されていますが、Visual Studioの単体テストにはASP.NET Webアプリケーション上のメソッドをテストする仕組みがきちんと用意されています。
操作手順
作業を開始する前に、テスト対象としているメソッドを確認しておきます。これはリスト4のようになっています。
/// <summary>
/// 指定された仮想パスを物理パスに変換してファイルにコンテンツを書き込みます。
/// </summary>
/// <param name="virtualPath"></param>
/// <param name="contents"></param>
/// <returns></returns>
public string WriteFile(string virtualPath, string contents)
{
//仮想パスから物理パスへの変換
string fileName = Server.MapPath(virtualPath);
//ファイルの書き込み
using (StreamWriter writer = new StreamWriter(fileName, false, Encoding.Default))
{
writer.Write(contents);
writer.Close();
}
return fileName;
}
このメソッドでは、継承元クラスのPageクラスに定義されたServerプロパティ(HttpServerUtilityクラスのインスタンス)のMapPathメソッドを使ってWebアプリケーションの仮想パスからコンピュータ上の物理パスへのパス変換を行ったうえで該当パスへのファイルの生成を行っています。HttpServerUtility.MapPathメソッドはASP.NET環境がないと正しく動作しないため、テストの実行がやや面倒な状況になっています。
とはいえ、面倒なところはVisual Studioが助けてくれるので、今まで通りに単体テストを作成してみてください。なお、付属のサンプルではテストプロジェクトを新しく作成していますが、先ほどまで利用していたものを使っても構いません。WriteFileメソッドのテストメソッドを作成すると、リスト5のようなテストメソッドが完成します。
/// <summary>
///WriteFile のテスト
///</summary>
// TODO: UrlToTest 属性が ASP.NET ページへの URL を指定していることを確認します (たとえば、
// http://.../Default.aspx)。これはページ、Web サービス、または WCF サービスのいずれをテストする
//場合でも、Web サーバー上で単体テストを実行するために必要です。
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("D:\\CodeZine-Test-05\\WebApplication1", "/")]
[UrlToTest("http://localhost:12888/")]
public void WriteFileTest()
{
_Default target = new _Default(); // TODO: 適切な値に初期化してください
string virtualPath = string.Empty; // TODO: 適切な値に初期化してください
string contents = string.Empty; // TODO: 適切な値に初期化してください
string expected = string.Empty; // TODO: 適切な値に初期化してください
string actual;
actual = target.WriteFile(virtualPath, contents);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("このテストメソッドの正確性を確認します。");
}
今までの単体テストと異なるのは、メソッドの属性として、HostType、AspNetDevelopmentServerHost、UrlToTestの3つの属性が追加されている点です。なお、AspNetDevelopmentServerHost属性とUrlToTest属性についてはテストを作成した環境によって定義される文字列に差がありますが、その環境に最適化された内容となっているので、リスト5の内容と異なっている可能性があることに注意してください。これらの属性以外の点については今までの単体テストと同じなので、TODOの部分を適切に書き換えて単体テストを作成してください。今回の場合は、リスト6の内容でテストを成功させることができます。
~属性は省略~
public void WriteFileTest()
{
_Default target = new _Default();
string virtualPath = "/Test.txt";
string contents = "これはテストです。";
string expected = contents;
string fileName = target.WriteFile(virtualPath, contents);
string actual;
//書き込んだファイルを読み込んでチェック
actual = File.ReadAllText(fileName, Encoding.Default);
Assert.AreEqual(expected, actual);
}
この単体テストでは、テスト対象メソッドがファイルを書き込むメソッドとなっているため、テストコードで書き込まれたファイルを読み込んで内容を確認しています。この状態でも単体テストの実行は可能でしたが、もう一歩進めて、他のコンピュータに移動したときでもテストが正しく実行されるように構成していきます。
まず、リスト6相当の単体テストメソッドでAspNetDevelopmentServerHost属性をリスト7のように編集します。
[TestMethod()]
[HostType("ASP.NET")]
[AspNetDevelopmentServerHost("%PathToWebRoot%\\WebApplication1", "/")]
[UrlToTest("http://localhost:12888/")]
public void WriteFileTest()
{
~中略~
}
