C#でMSTestのテストプロジェクトを使用してテストする際、
テスト対象のクラスのプライベートフィールドの値を変えたいことがあります。
たとえば、下記のようなクラスがあったとします。
public class Sample { private int a = 0; public bool OK { get { return this.a > 50; } } }
OKプロパティはプライベートフィールドaが50より大きい場合にtrueとなります。
下記のようなテストメソッドで、OKの戻り値の確認をしたい場合があります。
[TestMethod] public void TestMethod1() { Sample sample = new Sample(); // ここでsample.aを50より大きい値にしたい Assert.IsTrue(sample.OK); }
.NET Frameworkのプロジェクトであれば下記のようにPrivateObjectが使用できます。
[TestMethod] public void TestMethod1() { Sample sample = new Sample(); PrivateObject privateObject = new PrivateObject(sample); privateObject.SetFieldOrProperty("a", 51); Assert.IsTrue(sample.OK); }
PrivateObjectのコンストラクタにインスタンスを渡します。
そしてPrivateObjectのSetFieldOrPropertyメソッドでフィールド名と値を指定すると設定ができます。
ただ、このPrivateObjectは.NET Frameworkでないと使用できないため、.NET8などのプロジェクトでは使用できません。
そこで、別の方法、リフレクションを使用する方法です。
[TestMethod] public void TestMethod2() { Sample sample = new Sample(); FieldInfo fieldInfo = sample.GetType().GetField("a", BindingFlags.NonPublic | BindingFlags.Instance); fieldInfo.SetValue(sample, 51); Assert.IsTrue(sample.OK); }
インスタンスのTypeからフィールド名指定でField情報を取得します。
その際はNonPublicやInstanceといったフラグでプライベートフィールドであることを指定します。
一致するものがあればFieldInfoが返り、なければnullが返ります。
取得できれば、そのSetValueメソッドに、インスタンスと設定したい値を渡してやると設定できます。