すべての単体テストを独自のプロジェクトに入れました。単体テストのためだけに、特定のクラスを internal ではなく public にする必要があることがわかりました。これを行う必要がないようにする方法はありますか。クラスを封印ではなく公開することによるメモリへの影響は何ですか?
5 に答える
.NET を使用している場合、InternalsVisibleToアセンブリ属性を使用すると、"フレンド" アセンブリを作成できます。これらは、他のアセンブリの内部クラスおよびメンバーへのアクセスが許可されている特定の厳密な名前のアセンブリです。
これは、関連するアセンブリを緊密に結合するため、慎重に使用する必要があります。InternalsVisibleTo の一般的な用途は、単体テスト プロジェクトです。上記の理由により、実際のアプリケーション アセンブリでの使用には適していない可能性があります。
例:
[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{
それが内部クラスである場合、単独で使用されてはなりません。したがって、そのオブジェクトを内部で使用する他のクラスをテストする以外に、実際にテストするべきではありません。
クラスのプライベート メンバーをテストしてはならないのと同様に、DLL の内部クラスをテストしてはなりません。これらのクラスは、一般にアクセス可能なクラスの実装の詳細であるため、他の単体テストを通じて十分に実行する必要があります。
内部実装の詳細をテストするとテストが脆弱になるため、クラスの動作のみをテストしたいという考えです。すべてのテストを中断することなく、クラスの実装の詳細を変更できる必要があります。
そのクラスを本当にテストする必要があることがわかった場合は、そもそもそのクラスが内部である理由を再検討することをお勧めします。
文書化の目的で
Type.GetType
または、メソッドを使用して内部クラスをインスタンス化することもできます
例
//IServiceWrapper is public class which is
//the same assembly with the internal class
var asm = typeof(IServiceWrapper).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm.GetType("Namespace.ServiceWrapper");
return (IServiceWrapper<T>)Activator
.CreateInstance(type, new object[1] { /*constructor parameter*/ });
ジェネリック型の場合、次のように異なるプロセスがあります。
var asm = typeof(IServiceWrapper).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm.GetType("Namespace.ServiceWrapper`1");
var genType = type.MakeGenericType(new Type[1] { typeof(T) });
return (IServiceWrapper<T>)Activator
.CreateInstance(genType, new object[1] { /*constructor parameter*/});
クラスはパブリックとシールの両方にすることができます。
しかし、そうしないでください。
内部クラスをリフレクトするツールを作成し、リフレクションを介してすべてにアクセスする新しいクラスを発行できます。MSTest はそれを行います。
編集:つまり、元のアセンブリにテスト用のものを含めたくない場合。これは、メンバーが非公開の場合にも機能します。