I'm trying to unit test some Active Directory code, pretty much the same as outlined in this question:
Create an instance of DirectoryEntry for use in test
The accepted answer suggests implementing a wrapper/adapter for the DirectoryEntry
class, which I have:
public interface IDirectoryEntry : IDisposable
{
PropertyCollection Properties { get; }
}
public class DirectoryEntryWrapper : DirectoryEntry, IDirectoryEntry
{
}
The problem is that the "Properties" property on my IDirectoryEntry
mock is not initialised. Trying to set the mock up like this:
this._directoryEntryMock = new Mock<IDirectoryEntry>();
this._directoryEntryMock.Setup(m => m.Properties)
.Returns(new PropertyCollection());
Results in the following error:
The type 'System.DirectoryServices.PropertyCollection' has no constructors defined
As I understand it, this error is thrown when trying to instantiate a class with internal constructors only:
The type '...' has no constructors defined
I have tried to write a wrapper/adapter for the PropertyCollection
class but without a public constructor I can't figure out how to instantiate or inherit from the class.
So how can I mock/setup the "Properties" property on the DirectoryEntry
class for testing purposes?
Thanks to Chris's suggestions here is a code sample for my eventual solution (I went with his option 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; }
}
Used as follows:
this._directoryEntryMock = new Mock<IDirectoryEntry>();
this._directoryEntryMock
.Setup(m => m.Properties)
.Returns(new Hashtable()
{
{ "PasswordExpirationDate", SystemTime.Now().AddMinutes(-1) }
});
I don't think that you'll be able to mock or create an instance of PropertyCollection
. There are ways of overcoming this, but they require you to convert your derived wrapper class to be more of an actual wrapper, encapsulating a DirectoryEntry
object and providing accessors, not extending it. Once you've done that, you have these options:
Properties
property as one of the underlying collection types that PropertyCollection
implements (IDictionary
, ICollection
or IEnumerable
), if that is sufficient for your needsPropertyCollection
, and create a new one to wrap directoryEntry.Properties
each time the Properties
accessor is calledIDirectoryEntry
/DirectoryEntryWrapper
that return what you need without having to expose a Properties
property1 might be fine as a workaround, if you're OK accessing the properties through one of the underlying collection types. 2 will require you to implement every method and property of PropertiesCollection
in the wrapper, calling through to the encapsulated object underneath, but would be the most flexible. The easiest (but least flexible) is 3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With