Moqを使用して内部コンストラクターで型をモックする
Microsoft SyncFrameworkのクラスをモックしようとしています。内部コンストラクターのみがあります。私が以下を試すとき:
_var fullEnumerationContextMock = new Mock<FullEnumerationContext>();
_
このエラーが発生します:
System.NotSupportedException:親にはデフォルトのコンストラクターがありません。デフォルトのコンストラクターは明示的に定義する必要があります。
これはスタックトレースです:
System.Reflection.Emit.TypeBuilder.DefineDefaultConstructorNoLock(MethodAttributes属性)System.Reflection.Emit.TypeBuilder.DefineDefaultConstructor(MethodAttributes属性)System.Reflection.Emit.TypeBuilder.CreateTypeNoLock()System.Reflection.Emit.TypeBuilder.CreateType()Castle。 DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType()Castle.DynamicProxy.Generators.ClassProxyGenerator.GenerateCode(Type [] interfaces、ProxyGenerationOptions options)Castle.DynamicProxy.DefaultProxyBuilder.CreateClassProxy(Type classToProxy、Type [] additionalInterfacesToProxy、ProxyGenerationOptions options)Castle。 DynamicProxy.ProxyGenerator.CreateClassProxyType(Type classToProxy、Type [] additionalInterfacesToProxy、ProxyGenerationOptions options)Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy、Type [] additionalInterfacesToProxy、ProxyGenerationOptions options、Object []コンストラクター引数、IInterceptor []インターセプター)Castle.DynamicProxy。 ProxyGenerator.Create ClassProxy(Type classToProxy、Type [] additionalInterfacesToProxy、ProxyGenerationOptions options、IInterceptor []インターセプター)Castle.DynamicProxy.ProxyGenerator.CreateClassProxy(Type classToProxy、Type [] AdditionalInterfacesToProxy、IInterceptor []インターセプター)Moq.Mock
1.<InitializeInstance>b__0() Moq.PexProtector.Invoke(Action action) Moq.Mock
1.InitializeInstance ()
どうすればこれを回避できますか?
Moqはその型のオブジェクトをインスタンス化できないため、パブリックコンストラクターを持たない型をモックすることはできません。テストしようとしているものに応じて、いくつかのオプションがあります。
- ファクトリオブジェクトまたはFullEnumerationContextのインスタンスを取得する他の方法がある場合は、おそらくそれを使用できます(申し訳ありませんが、同期フレームワークに精通していません)
- プライベートリフレクションを使用してFullEnumerationContextをインスタンス化することはできますが、その場合、メソッドをモックすることはできません。
- テスト対象のコードが呼び出すことができるモック可能なインターフェイスやラッパーオブジェクトを導入できます。ランタイム実装は実際のFullEnumerationContextに委任しますが、テスト時実装は必要なアクションを実行します。
私はMoqの専門家ではありませんが、コンストラクターの引数を指定する必要があると思います。 Rhino Mocksでは、次のように指定します。
var fullEnumerationContextMock = new Mock<FullEnumerationContext>(arg1, arg2);
それはおそらくMoqでも同様です。
marcind からの回答に基づいて、モックするインターフェイス(IFullEnumerationContext
)を作成しました。次に、テストしようとしているメソッドのオーバーロードが2つあり、1つはFullEnumerationContext
とIFullEnumerationContext
を取る別のもの。気分は良くありませんが、機能します。より良い提案や改善があれば歓迎します。
public override void EnumerateItems(FullEnumerationContext context)
{
List<ItemFieldDictionary> listItemFieldDictionary = EnumerateItemsCommon();
context.ReportItems(listItemFieldDictionary);
}
public void EnumerateItems(IFullEnumerationContext context)
{
List<ItemFieldDictionary> listItemFieldDictionary = EnumerateItemsCommon();
context.ReportItems(listItemFieldDictionary);
}
実際にできます。 AssemblyInfo.csファイルを開き、最後に次の行を追加します。
[Assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
テスト対象システムプロジェクトでは、次のものが必要です。
protected internal
SUTクラスでのコンストラクターの可視性(例:FullEnumerationContext
)AssemblyInfo.cs
内部をテストプロジェクトに公開する必要があります。[Assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]