2009-05-19 6 views
1

私がテストしようとしているクラスに問題があります。私はプライベート列挙型を宣言しており、コード内の汎用辞書にその列挙型を使用しています。この列挙型はこのクラスの外では意味を持ちませんが、プライベートメソッドで使用されます。私がコードを生成すると、アクセサは汎用辞書型に書き込まれますが、テストを使用しようとすると無効キャスト例外がスローされます。Visual Studioでプライベートタイプを含むジェネリックスを使用する方法ユニットテスト

MyClass_Accessor target = new MyClass_Accessor(); 
Dictionary<MyClass_Accessor.MyEnum, long> dictionary = new Dictionary<MyClass_Accessor.MyEnum, long>(); 
dictionary.Add(MyClass_Accessor.Myenum.EnumValue, 1); 
target.Method(dictionary); //Throws invalid cast exception here. 

例外がアクセッサ=>列挙の一般的な辞書は、長い長い、MYCLASS =>列挙型に変換することができないことです。

私の作業クラスを変更する以外に、この方法をテストする方法はありますか?

答えて

4

InternalsVisibleToアセンブリ属性を使用して、内部オブジェクトを内部構造に変更できます。 (内部列挙型にプライベート列挙型を変更できない場合は、これは機能しませんが、通常は受け入れられます)

AssemblyAtestによってユニットテストされているAssemblyAというアセンブリがあるとします。そしてAssemblyAIntegTestによってテストの統合は、あなたのAssemblyInfo.csで次のファイル固執することができます:あなたがあなたの主なアセンブリに署名する場合、あなたはまた、培養、あなたのテストアセンブリに署名し、完全修飾する必要があります

using System.Runtime.CompilerServices; 

// ... 

[assembly: InternalsVisibleTo("AssemblyATest")] 
[assembly: InternalsVisibleTo("AssemblyAIntegTest")] 

をし、主キー付きアセンブリ名。

+0

辞書が指定された型ではなく実際の型であるため、これが機能すると仮定しています。私はこれを0日にしますが、これはクラスの目的を変更することなくおそらく動作しますが、これをサポートする方法を見つけるとうまくいくでしょう。 – Spence

+0

Microsoftは単体テストをサポートするためにInternalsVisibleTo属性を追加しました。これは主な目標の1つであり、マイクロソフト独自のライブラリの目的に使用されています(使用例の例が必要な場合は、Enterprise Library 3.0と4.0が重要な例です)。 – jrista

0

質問が私にはっきりしないことを認めなければなりません。しかし、あなたは公共の呼び出し元を介してプライベートメソッドをテストする必要があるように見えます。

ほとんどの場合、TDDでは、テストを満たすパブリックメソッドを作成し、必要に応じてプライベートテストでそれをリファクタリングします。

+0

私のTDDはありません: '(。私は既存のコードベースにテストを追加するように求められました... ここからすべての学習曲線です。したがって、基本的には、この関数のために働いているテストをそのまま残しておく方法はありません。呼び出しをリファクタリングすると、テストを失うことになります。 – Spence

0

私は私的な定義も持っているが、コードを見ても辞書のオブジェクトから有効な値が選択されていないように見えます。

コードを次のようにしてはいけませんか?

target.Method(dictionary[0]); 

さて、あなたのコメントの後に。

次のコードは、クラスのプライベートメソッド(PaDeviceManager)を使用したテストから取得したものですが、要件に合わせて調整できますか?

PaDeviceManager paDeviceManager = PaDeviceManager.Create; 
PrivateObject param0 = new PrivateObject(paDeviceManager); 
PaDeviceManager_Accessor target = new PaDeviceManager_Accessor(param0); 
PaDeviceManager_Accessor(); 
+0

メソッドは値の辞書を取ります。その状態を共有状態にします。私はそれが辞書の値を変換することを期待しています。 – Spence

0

私はあなたの状況の下でこれが実行する必要があるかもしれないテストであることを認めるでしょう。その場合は、jristaの回答が従うべきものです(InternalsVisibleTo)。

しかし、私はあなたが通常、クラスの非公開APIをテストすることになっているとは思わないと思います。この列挙型がクラスに対してプライベートであるため、クラスの内部でのみ使用されている場合は、いずれのユニットテストでも発生しません。

ユニットの目的は、クラスのパブリック(バーチャル/抽象的な保護を含む)APIが期待どおりに機能することを確認することです。このプライベート列挙型などの実装の詳細に依存するテストを含めることによって、将来は実装を変更することが不可能になります(たとえば、列挙型を必要としない実装など)。

関連する問題