2013-08-05 3 views
2

Я пытаюсь модульного тестирования кода некоторые Active Directory, почти так же, как описано в этом вопросе:Дразнящий свойство «Свойства» из DirectoryEntry

Create an instance of DirectoryEntry for use in test

Принятый ответ предполагает реализацию обертку/адаптер для DirectoryEntry класса, который у меня есть:

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

public class DirectoryEntryWrapper : DirectoryEntry, IDirectoryEntry 
{ 
} 

Проблема заключается в том, что "Properties" собственность на моем IDirectoryEntry макете I s не инициализируется. Попытка установить макет, как это:

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

Результатов в следующей ошибке:

типа «System.DirectoryServices.PropertyCollection» имеет никаких конструкторов не определены

Как я понимаю, эта ошибка возникает при попытке создать экземпляр класса только с внутренними конструкторами:

The type '...' has no constructors defined

Я попытался написать оболочку/адаптер для класса PropertyCollection, но без публичного конструктора я не могу понять, как создавать или наследовать класс.

Итак, как я могу издеваться/настраивать «Свойства» на классе DirectoryEntry для целей тестирования?

ответ

3

Я не думаю, что вы сможете высмеять или создать экземпляр PropertyCollection. Есть способы преодоления этого, но они требуют, чтобы вы преобразовали свой производный класс-оболочку в более фактическую оболочку, инкапсулируя объект DirectoryEntry и предоставляя аксессуры, не расширяя его. После того, как вы сделали это, у вас есть следующие варианты:

  1. Определить тип возвращаемого Properties имущества в качестве одного из основных типов коллекций, PropertyCollection инвентаря (IDictionary, ICollection или IEnumerable), если это является достаточным для вашего потребности
  2. Создание заключающую класса-оболочки с интерфейсом для PropertyCollection, и создать новый, чтобы обернуть directoryEntry.Properties каждый раз Properties аксессора называется
  3. Создать методы на IDirectoryEntry/DirectoryEntryWrapper, которые возвращают то, что вы необходимо, не выставляя объект Properties

1 может быть хорошо, как обходной путь, если вы в порядке доступа к свойствам через один из базовых типов коллекций. 2 потребует, чтобы вы реализовали каждый метод и свойство PropertiesCollection в оболочке, обратившись к инкапсулированному объекту снизу, но были бы наиболее гибкими. Самый простой (но наименее гибкий) - 3.

6

Благодаря предложениям Криса здесь приведен пример кода для моего окончательного решения (я пошел с его вариант 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) } 
     });