6

我正在尝试对一些 Active Directory 代码进行单元测试,与此问题中概述的几乎相同:

创建用于测试的 DirectoryEntry 实例

接受的答案建议为DirectoryEntry该类实现一个包装器/适配器,我有:

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

public class DirectoryEntryWrapper : DirectoryEntry, IDirectoryEntry
{
}

问题是我的模拟上的“属性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的基础集合类型之一,如果这足以满足您的需要PropertyCollectionIDictionaryICollectionIEnumerable
  2. 创建一个带有接口的封装包装类,并在每次调用访问器时PropertyCollection创建一个新的包装类directoryEntry.PropertiesProperties
  3. IDirectoryEntry在/上创建DirectoryEntryWrapper返回所需内容的方法,而无需公开Properties属性

如果您可以通过其中一种基础集合类型访问属性,则 1 作为一种解决方法可能很好。2 将要求您实现包装器中的每个方法和属性PropertiesCollection,调用下面的封装对象,但将是最灵活的。最简单(但最不灵活)是 3。

于 2013-08-05T11:39:20.210 回答