6

この質問で概説されているのとほぼ同じ、いくつかの Active Directory コードの単体テストを試みています。

テストで使用する DirectoryEntry のインスタンスを作成します

DirectoryEntry受け入れられた答えは、私が持っているクラスのラッパー/アダプターを実装することを提案しています:

public interface IDirectoryEntry : IDisposable
{
    PropertyCollection Properties { get; }
}

public class DirectoryEntryWrapper : DirectoryEntry, IDirectoryEntry
{
}

問題は、モックの「 Properties」プロパティが初期化されていないことです。IDirectoryEntryこのようにモックアップを設定しようとしています:

this._directoryEntryMock = new Mock<IDirectoryEntry>();
this._directoryEntryMock.Setup(m => m.Properties)
                        .Returns(new PropertyCollection());

次のエラーが発生します。

タイプ 'System.DirectoryServices.PropertyCollection' にはコンストラクターが定義されていません

私が理解しているように、内部コンストラクターのみでクラスをインスタンス化しようとすると、このエラーがスローされます。

タイプ「...」にはコンストラクターが定義されていません

クラスのラッパー/アダプターを作成しようとしましたPropertyCollectionが、パブリックコンストラクターがないと、クラスをインスタンス化または継承する方法がわかりません。

では、テスト目的でクラスの「 Properties」プロパティをモック/セットアップするにはどうすればよいですか?DirectoryEntry

4

2 に答える 2

11

Chris の提案のおかげで、ここに私の最終的な解決策のコード サンプルがあります (私は彼のオプション 1 を使用しました)。

public interface IDirectoryEntry : IDisposable
{
    IDictionary Properties { get; }
}

public class DirectoryEntryWrapper : IDirectoryEntry
{
    private readonly DirectoryEntry _entry;

    public DirectoryEntryWrapper(DirectoryEntry entry)
    {
        _entry = entry;
        Properties = _entry.Properties;
    }

    public void Dispose()
    {
        if (_entry != null)
        {
            _entry.Dispose();
        }
    }

    public IDictionary Properties { get; private set; }
}

次のように使用します。

this._directoryEntryMock = new Mock<IDirectoryEntry>();
this._directoryEntryMock
        .Setup(m => m.Properties)
        .Returns(new Hashtable()
        {
            { "PasswordExpirationDate", SystemTime.Now().AddMinutes(-1) }
        });
于 2013-08-05T12:28:28.530 に答える
4

のインスタンスをモックしたり作成したりできるとは思いませんPropertyCollection。これを克服する方法はありますが、派生したラッパー クラスを実際のラッパーのように変換し、DirectoryEntryオブジェクトをカプセル化し、アクセサーを提供して拡張する必要があります。それが完了したら、次のオプションがあります。

  1. 必要に応じて、 ( 、または) を実装Propertiesする基になるコレクション型の 1 つとして、プロパティの戻り値の型を定義します。PropertyCollectionIDictionaryICollectionIEnumerable
  2. のインターフェイスを持つカプセル化ラッパー クラスを作成し、アクセサが呼び出されるたびPropertyCollectionにラップする新しいクラスを作成します。directoryEntry.PropertiesProperties
  3. プロパティを公開せずに必要なものを返すIDirectoryEntry/のメソッドを作成するDirectoryEntryWrapperProperties

基になるコレクション型のいずれかを介してプロパティにアクセスしても問題ない場合は、回避策として 1 で問題ない可能性があります。2 では、ラッパー内のすべてのメソッドとプロパティを実装PropertiesCollectionし、その下にあるカプセル化されたオブジェクトを呼び出す必要がありますが、最も柔軟です。最も簡単な (ただし柔軟性が最も低い) のは 3 です。

于 2013-08-05T11:39:20.210 に答える