C# で Private メソッドを単体テストするための方法

C#でPrivateメソッドを単体テストするための方法
Privateなメソッドで単体テストを行いたい場合、リフレクションを使う方法、アクセス修飾子を internal に変更する方法があります。
楽だからという理由で全部 Public に変えてしまうのは NG です。公開範囲を適切にコントロールすることがバグを減らすためには必須です。


リフレクションを使った単体テスト

リフレクションを使うため、パフォーマンスはやや劣ります。ただ、既存のコードに手を入れなくてもコードを追加できるメリットがあります。

テスト対象クラス
public class Class1 
{ 
 private string GetHoge(string value)
 {
  return value + "Hoge";
 }
}

テストクラス
[TestClass] 
public class UnitTest1 
{ 
 [TestMethod] 
 public void GetHoge_Test() 
 { 
  var value = "ほげ";
  var biz = new PrivateObject(new Class1());
  var result = biz.Invoke("GetHoge", value);
   
  Assert.AreEqual(result.ToString(), value + "Hoge");
 }
}

internalの単体テスト

対象メソッドの private を internal へ変更します。対象クラスの AssemblyInfo に公開対象にするテストプロジェクトを追加することで、テスト側からも見えるようになります。

準備として、Properties 下の AssemblyInfo.cs に以下を追加します(参照したいテスト暮らすの名前空間)。
[assembly: InternalsVisibleTo("UnitTestProject1")]

テスト対象クラス
public class Class1 
{ 
 internal string GetHoge(string value) 
 { 
  return value + "Hoge"; 
 } 
} 

テストクラス
namespace UnitTestProject1 
{ 
    [TestClass] 
    public class UnitTest1 
    { 
        [TestMethod] 
        public void GetHoge_Test() 
        { 
            var value = "ほげ"; 
            var biz = new Class1(); 
            var result = biz .GetHoge(value); 
 
            Assert.AreEqual(result.ToString(), value + "Hoge"); 
        } 
    } 
} 

結論としては、実はリフレクションを使っても、極端にパフォーマンスが悪くなるわけではなかっ
たりします(あまり極端に遅くなったケースは、私は見たことがないです)。
それぞれの現場の思想(好み)にも関係するような話なので、どっちも覚えておくといいですね。

このブログの人気の投稿

コピーした行の挿入が表示されない時はフィルタされていないかチェック

Excel で一部の図形だけ固定する