🙆

【Unity】NUnitでInternalコンストラクタをテストしたい

に公開

問題点:NUnitでテストからinternalコンストラクタにアクセスできない

・UnityでNUnitを利用する際、テストコードと被テストコードの両方をAssembly Definition Files (.asmdef)によってそれぞれ別アセンブリに分離している
・テストコードから、別アセンブリにある被テストコードのinternalなコンストラクタ(クラス・メソッド・プロパティなども含む)にアクセスできない

解決策:AssemblyInfo.csを作成し指定したアセンブリからのアクセスを可能に設定する

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

問題が発生したシチュエーション

  1. 開発中にBuilderパターンを採用
  2. Builderクラスで生成するクラスのコンストラクタをinternalに設定
  3. テストコードから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のコンストラクタにアクセス不可

下の画像のようなテストを組んだ際、コンストラクタがアクセスできないためエラーが発生

解決策の説明

  1. AssemblyInfo.csという名前のファイルを、被テストコードのAssembly Definition Files(.asmdef)と同じフォルダーに作成
  2. 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.csInternalsVisibleToを記述
  • .asmdefファイルのNameInternalsVisibleTo指定することで、NUnitからinternalをテスト可能

Discussion