我正在慢慢地開始單元測試和嘲弄,但這是一個緩慢的過程。我嘗試過使用這個Active Directory代碼進行單元測試。這個問題與AD並不嚴格相關。太多的接口和包裝?
class ActiveDirectoryQueryer {
DirectorySearcher mSearcher;
public ActiveDirectoryQueryer() {
var searcher = new DirectorySearcher(...);
}
public void GetAllMailEntries() {
MailEntries =
mSearcher
.FindAll()
.Select(result => result.GetDirectoryEntry())
.Select(BuildNewADUser)
.ToList();
}
static ActiveDirectoryUser BuildNewADUser(DirectoryEntry pDirectoryEntry) {
return ActiveDirectoryUser.Create(
pDirectoryEntry.Guid,
(pDirectoryEntry.Properties["name"].Value ?? "").ToString(),
(pDirectoryEntry.Properties["mail"].Value ?? "").ToString()
);
}
所以,我想單元測試GetAllMailEntries
的方法。爲了使用MOQ來做到這一點,我不得不手動生成各種.NET類型的接口和包裝器,並且改變了上面許多接口的引用(如IDirectoryEntry
)。下面的每個IXxxx
接口都有一個關聯的包裝類XxxxWrapper
。總的來說,我爲這個測試添加了至少12個新的源文件。以下是單元測試的結果:
[TestMethod]
public void TestGetAllMailEntries() {
var mockSearcher = new Mock<IDirectorySearcher>();
var mockResultCollection = new Mock<ISearchResultCollection>();
var mockSearchResult = new Mock<ISearchResult>();
var mockDirectoryEntry = new Mock<IDirectoryEntry>();
var mockPropertyCollection = new Mock<IPropertyCollection>();
var nameMockPropertyValueCollection = new Mock<IPropertyValueCollection>();
var mailMockPropertyValueCollection = new Mock<IPropertyValueCollection>();
const string name = "SomeNameValue";
const string mailAddress = "SomeMailAddress";
nameMockPropertyValueCollection.SetupGet(pvc => pvc.Value).Returns(name);
mailMockPropertyValueCollection.SetupGet(pvc => pvc.Value).Returns(mailAddress);
mockPropertyCollection.SetupGet(pc => pc["name"]).Returns(nameMockPropertyValueCollection.Object);
mockPropertyCollection.SetupGet(pc => pc["mail"]).Returns(mailMockPropertyValueCollection.Object);
mockDirectoryEntry.SetupGet(de => de.Properties).Returns(mockPropertyCollection.Object);
mockSearchResult.Setup(sr => sr.GetDirectoryEntry()).Returns(mockDirectoryEntry.Object);
mockResultCollection.Setup(results => results.GetEnumerator()).Returns(new List<ISearchResult> { mockSearchResult.Object }.GetEnumerator());
mockSearcher.Setup(searcher => searcher.FindAll()).Returns(mockResultCollection.Object);
var queryer = new ActiveDirectoryQueryer(mockSearcher.Object);
queryer.GetAllMailEntries();
Assert.AreEqual(1, queryer.MailEntries.Count());
var entry = queryer.MailEntries.Single();
Assert.AreEqual(name, entry.Name);
Assert.AreEqual(mailAddress, entry.EmailAddress);
}
擁有這麼多接口和包裝類是否正常? (因爲.NET類型不能實現我的接口,所以包裝是必需的。)
我簡要回顧你的設置和以下很快襲擊我。而不是靜態的「BuildNewADUser」功能。把它放到一個新的服務(一個接口)中,並給它它所需要的。例如,IActiveDirectoryUserFactory.Create(Guid id,字符串名稱,字符串電子郵件)返回一個ActiveDirectoryUser。現在,您可以更輕鬆地單元測試您的初始類,只需模擬一個界面,這是一種方法。 –
@Atoms謝謝,我有點喜歡這個想法,但我沒有看到如何讓我不嘲笑'DirectorySearcher'。 –