クラスのprivateなフィールド、プロパティの値を外から変えて、UnitTestする(.NET6)

もくじ
https://tera1707.com/entry/2022/02/06/144447#UnitTest

やりたいこと

クラスの中で持っているprivateなフィールドやプロパティの値を外からいじって、そのクラスをユニットテストしたい。

以前、.NET6でprivateやinternalなメソッドを呼ぶ方法を調べて、今回やりたいようなことは できるんだろうなと思っていたが実際にやってはいなかったので、ほんとにできるか試したい。

前提

.NET6

やりかた

以前と同じように、リフレクションを使う。

サンプルコード

namespace GetFieldTest
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var mc1 = new MyClass();
            mc1.DisplayField();

            var mc2 = new MyClass();

            // まず対象クラスのtypeを取得
            var type = typeof(MyClass);

            // そのtypeでGetFieldする
            var field = type.GetField("_fieldString", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
            var prop = type.GetProperty("_propertyString", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

            // クラスのインスタンスを指定して、取得したFieldに対してSetValueする
            field.SetValue(mc2, "Irekonda Field Mojiretsu");
            prop.SetValue(mc2, "Irekonda Property Mojiretsu");

            // 値をセットしたので、値を書き換えたクラスでメソッドを読んでみる
            mc2.DisplayField();
        }
    }

    // テスト対象のクラス
    internal class MyClass
    {
        private string _fieldString = "Motomotono Field Mojiretsu";
        private string _propertyString { get; set; } = "Motomotono Property Mojiretsu";

        public void DisplayField()
        {
            Console.WriteLine(_fieldString);
        }
        public void DisplayProperty()
        {
            Console.WriteLine(_propertyString);
        }
    }
}

実行結果

2回目によんだときは、フィールドとプロパティの値が書き換えられている。

注意

Propertyのほうは、`setまたはinitがないと、SetValueのところでArgumentExceptionという例外がでる。

参考

クラス自体がinternalなときのUnitTest(.NET6版)

https://tera1707.com/entry/2022/01/29/173244

private、internalなメソッドのUnitTest(.NET6版)

https://tera1707.com/entry/2022/01/29/202451