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