はじめに
internal
クラスに対してテストコードを書こうとした場合、アクセス制限に引っかかりテストコードが書けない。
この記事ではその場合の解決方法をまとめる。
現象
あるプロジェクトで以下のようなコードがあったとしよう。
Calculator
というクラスに2つの値を渡し、足し算した結果を表示するプログラムだ。
namespace InternalClassSample
{
class Program
{
static void Main(string[] args)
{
var calculator = new Calculator(1, 2);
Console.WriteLine(calculator.DoAddition());
}
}
}
namespace InternalClassSample
{
internal class Calculator
{
private readonly int _left;
private readonly int _right;
public Calculator(int left, int right)
{
_left = left;
_right = right;
}
public int DoAddition()
{
return _left + _right;
}
}
}
どうやらこのCalculator
クラスは同一アセンブリ内でしか使用されていないため、internal
クラスとして定義されているようだ。
さて、このたびプロジェクトでは品質を上げるためにテストコードを書くことになったとしよう。
早速、Calculator
クラスに対してテストコードを書くため、テストプロジェクトを用意してテストコードを書いてみた。
namespace InternalClassSample.UnitTest
{
[TestClass]
public class UnitTest1
{
[TestMethod]
public void Test_DoAddition()
{
var calculator = new InternalClassSample.Calculator(1, 2);
Assert.AreEqual(3, calculator.DoAddition());
}
}
}
早速コンパイルしてテストを走らせてみよう。
error CS0122: 'Calculator' はアクセスできない保護レベルになっています
残念なことにエラーになってしまった。
Calculator
クラスがinternal
であるために、新しく追加したテストプロジェクトからはアクセス制限に引っかかってしまうのである。
プロジェクトの方針としてテストコードを書かなければならないが、このままではテストコードを書けない。
このエラーを何とかして回避する方法はないだろうか?
解決方法
私がこの記事で伝える解決方法は以下の2つだ。
1. アクセス制限を緩める
2. 特定のアセンブリにだけinternalクラスを公開する
それぞれについて詳しく解説していこう。
アクセス制限を緩める
こちらの方法はかなり単純な方法だ。
Calclator
クラスのアクセス修飾子がinternal
だから見えないのだから、よりアクセス制限が緩いpublic
に変更し、テストコードのプロジェクトからも見えるようにすれば良い。
具体的には、コードを以下のように変更する。
// アクセス修飾子をinternalからpublicへ変更する
public class Calculator
この方法のメリットはinternalからpublicへ変えるだけなので、修正が簡単であることだ。
ただし、デメリットとして今後はどこからでも利用可能となるため、使用するべきではないところから呼び出されてしまう可能性が出てくる。
特にコードが膨大になっている場合、アクセス制限を緩めてしまうと、今後、様々な場所から呼び出されてしまい、変更が困難になる可能性もある。
特定のアセンブリにだけinternalクラスを公開する
こちらの方法は先程のデメリットを抑えつつ、修正もそれほど多くないためオススメの方法だ。
InternalsVisibleToAttribute
を使い、テストプロジェクトにだけinternal
クラスを公開すれば良い。
具体的にはCalculator
クラスが含まれるプロジェクトのAssemblyInfo.cs
に以下のコードを追記する。
[assembly: InternalsVisibleTo("InternalClassSample.UnitTest")]
こうすることでテストプロジェクトにだけinternal
クラスが見えるようになるため、アクセス制限を緩めたりせずにテストコードを書くことができる。
また、上記の1行を追加すれば良いだけなので、修正もそれほど多くならないはずだ。
まとめ
今回はinternal
クラスに対してテストコードを書く方法ということで、その方法をまとめてみた。
この記事を書くにあたってInternalsVisibleToAttribute
を初めて知ったが、今後テストコードを書く際に使えそうな機能なので覚えておきたいと思う。
それではまた。
TomoProg