MSTestでprivateメソッドをテストする

MSTestでprivateメソッドをテストする方法。

下記のサンプルクラスを使用します。

MyClassは、privateメソッドの”greet”と、staticのprivateメソッド”add”を持ちます。

public class MyClass
{
  private string greet(string name)
  {
    return "Hello " + name;
  }

  private static int add(int a, int b)
  {
      return a + b;
  }
}

privateメソッドのテスト

privateメソッドをテストするには、PrivateObjectクラスのInvokeメソッドを使用します。

[TestMethod]
public void TestGreet()
{
  var myClass = new MyClass();
  var pbObj = new PrivateObject(myClass);
  var actual = (string)pbObj.Invoke("greet", "World");
  Assert.AreEqual("Hello World", actual);
}

テスト対象のインスタンスを引数にして、PrivateObjectのオブジェクトを作成します。

実行するprivateメソッドの名前と、メソッドの引数をInvokeメソッドに渡します。
Invokeメソッドはobjectを返しますので、適切な型に変換します。

private staticのテスト

private staticメソッドをテストするには、PrivateTypeクラスのInvokeStaticメソッドを使用します。

[TestMethod]
public void TestAdd()
{
  PrivateType privateType = new PrivateType(typeof(MyClass));
  int actual = (int)privateType.InvokeStatic("add", 1, 2);
  Assert.AreEqual(3, actual);
}

staticなprivateメソッドをテストするには、テストするクラスを引数にしてPrivateTypeオブジェクトを作成します。

実行するstaticなprivateメソッドの名前と、メソッドの引数をInvokeStaticメソッドに渡します。
InvokeStaticメソッドはobjectを返しますので、適切な型に変換します。

親クラスのメソッドをテストするには

親クラスのプライベートメソッドをテストする場合は、PrivateObjectの引数に親クラスを指定する必要があります。

たとえば、SubClassのオブジェクトを使って、親クラス(MyClass)のaddメソッドをテストする場合です。

public class MyClass
{
    private string greet(string name)
    {
    return "Hello " + name;
    }

    private static int add(int a, int b)
    {
    return a + b;
    }
}

public class SubClass : MyClass
{
}

次のようにSubClassのオブジェクトでjプライベートメソッドを実行しようとするとMissingMethodException例外が発生し、「見つからないメンバーにアクセスしようとしました。」というエラーになる。

[TestMethod]
public void TestSubAdd()
{
  var subClass = new SubClass();
  var pbObj = new PrivateObject(subClass);
  var actual = (string)pbObj.Invoke("greet", "World"); // MissingMethodException「見つからないメンバーにアクセスしようとしました。」
  Assert.AreEqual("Hello World", actual);
}

PrivateObjectの引数にテストしたいクラス(MyClass)を指定することで、テストできます。

[TestMethod]
public void TestSubAdd()
{
  var subClass = new SubClass();
  var pbObj = new PrivateObject(subClass);
  //var pbObj = new PrivateObject(subClass, knew PrivateType(typeof(MyClass)));
  var actual = (string)pbObj.Invoke("greet", "World");
  Assert.AreEqual("Hello World", actual);
}

privateフィールドのテスト

privateフィールドの値を取得するには、PrivateObjectのGetField()メソッドを使用します。

public class MyClass
{
    private string name;
    public MyClass(string name)
    {
        this.name = name;
    }
}


[TestMethod]
public void TestNamet()
{
    var myClass = new MyClass("Hello World");
    var pbObj = new PrivateObject(myClass);
    var name = (string)pbObj.GetField("name");
    Assert.AreEqual("Hello World", name);
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です