🙆
【Unity】NUnitでInternalコンストラクタをテストしたい
問題点:NUnitでテストからinternalコンストラクタにアクセスできない
・UnityでNUnitを利用する際、テストコードと被テストコードの両方をAssembly Definition Files (.asmdef)によってそれぞれ別アセンブリに分離している
・テストコードから、別アセンブリにある被テストコードのinternalなコンストラクタ(クラス・メソッド・プロパティなども含む)にアクセスできない
解決策:AssemblyInfo.csを作成し指定したアセンブリからのアクセスを可能に設定する
-
AssemblyInfo.csという名前のファイルを、被テストコードのAssembly Definition Files(.asmdef)と同じフォルダーに作成 -
AssemblyInfo.csに指定したアセンブリからinternalへのアクセスを許可する設定を記述
問題が発生したシチュエーション
- 開発中にBuilderパターンを採用
- Builderクラスで生成するクラスのコンストラクタをinternalに設定
- テストコードからinternalのコンストラクタにアクセス不可
1.開発中にBuilderパターンを採用
Playerキャラの状態を表すクラスを定義し、そのクラスの生成をBuilderクラスに任せるという実装を採用
//状態のクラス
public class PCStateData : IPCStateData
{
public bool CanHorizontalMove { get; }
public bool CanJump {get;}
internal PCStateData(bool canHorizontalMove, bool canJump) =>
(CanHorizontalMove, CanJump) =
(canHorizontalMove, canJump);
}
2.Builderクラスで生成するクラスのコンストラクタをinternalに設定
このクラスは、今後の開発で変数や初期化パラメータが増える可能性があるため、生成をBuilderクラスに委譲
そのため、Builder以外からコンストラクタを呼べないようにinternalに設定
コンストラクタ:internal PCStateData(bool canHorizontalMove, bool canJump)
3.テストコードからInternalのコンストラクタにアクセス不可
下の画像のようなテストを組んだ際、コンストラクタがアクセスできないためエラーが発生

解決策の説明
-
AssemblyInfo.csという名前のファイルを、被テストコードのAssembly Definition Files(.asmdef)と同じフォルダーに作成 -
AssemblyInfo.csに指定したアセンブリからinternalへのアクセスを許可する設定を記述
1.AssemblyInfo.csという名前のファイルを、被テストコードのAssembly Definition Files(.asmdef)と同じフォルダーに作成
次の図を参考に.asmdefファイルと同じフォルダーにAssemblyInfo.csを作成

2.AssemblyInfo.csに指定したアセンブリからinternalへのアクセスを許可する設定を記述
AssemblyInfo.csに下記の内容を記述して保存
//AssemblyInfo.cs
#if UNITY_EDITOR
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("EditModeTests")]
#endif
InternalsVisibleToに指定する文字列は、テストコードの.asmdefファイルに定義されているNameなので、下図のように.asmdefのInspectorで確認

結果確認
上記のように設定した後、テストコードのinternalコンストラクタにアクセス可能となり、エラーが解消
なお、同時にinternalのクラスやメソッドにもアクセス可能

まとめ
-
internalはアセンブリ内のみ有効なアクセス修飾子 - 別アセンブリのテストからアクセスしたい場合、
AssemblyInfo.csにInternalsVisibleToを記述 -
.asmdefファイルのNameをInternalsVisibleTo指定することで、NUnitからinternalをテスト可能
Discussion