InternalsVisibleTo属性を利用した作り方
publicメソッド以外のメソッドの単体テストを作成するには、プライベートアクセッサーを利用するという方法がありました。しかし、先ほど少し触れたようにプライベートアクセッサーは本当のテスト対象クラスとはまったく異なるクラスであるため、クラスそのものをきちんと利用したい場合には具合が悪いことがあります。例が少し悪いですが、次のリスト6をご覧ください。
namespace ClassLibrary1 { public class Class1 { internal Class2 CreateClass2() { return new Class2(); } } internal class Class2 { } }
CreateClass2メソッドを対象にプライベートアクセッサーを利用した方法でテストメソッドを作成するとリスト7のようになります。
/// <summary> ///CreateClass2 のテスト /// </summary> [TestMethod()] [DeploymentItem("ClassLibrary1.dll")] public void CreateClass2Test() { Class1_Accessor target = new Class1_Accessor(); // TODO: 適切な値に初期化してください Class2_Accessor expected = null; // TODO: 適切な値に初期化してください Class2_Accessor actual; actual = target.CreateClass2(); Assert.AreEqual(expected, actual); Assert.Inconclusive("このテストメソッドの正確性を確認します。"); }
ここで、target.CreateClass2メソッドは本来であれば、Class2のインスタンスを返却してほしいところですが、Class2_Accessorクラスのインスタンスを返却してきてしまいます。処理そのものは継続することができますが、Class2のインスタンスかどうかを確認したい場合にはこれでは都合が悪いこともあります。
既にリスト7のテストメソッドを実際に作成されている場合にはお気づきかもしれませんが、テストメソッドを作成する際に図10のようなダイアログが表示されることがあります。
これは、テスト対象のメソッド(およびその引数、戻り値)にinternal属性がついたクラスを利用している場合に表示されます。この機能はあるアセンブリ内にあるinternal属性のクラスを指定した別のアセンブリにのみ公開するという機能です。VS2005のころはC#プロジェクトでしか利用できませんでしたが、VS2010(VS2008以降)ではVBプロジェクトでも利用することができるようになっています。この機能を利用してテストメソッドを作成するとリスト7のテストメソッドはリスト8のように変更されます。
/// <summary> ///CreateClass2 のテスト /// </summary> [TestMethod()] public void CreateClass2Test() { Class1 target = new Class1(); // TODO: 適切な値に初期化してください Class2 expected = null; // TODO: 適切な値に初期化してください Class2 actual; actual = target.CreateClass2(); Assert.AreEqual(expected, actual); Assert.Inconclusive("このテストメソッドの正確性を確認します。"); }
このようにpublicメソッドをテストする時となんら変わらない状態になりました。なお、InternalsVisibleTo属性はテストされる側のアセンブリのAssemblyInfo.cs(VBプロジェクトの場合はAssemblyInfo.vb)ファイル内に記述されています。InternalsVisibleTo属性の内容を変更したり削除したりする場合には確認する場所に注意してください。