Pages

2017/02/11

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"); 
        } 
    } 
} 

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