2011-04-18 98 views
1

假的目錄,我想對於類似這樣的代碼創建單元測試:的.NET單元測試

foreach (string domainName in Directory.GetDirectories(server.Path)) 
{ 
    HandleDomainDirectory(session, server, domainName); 
} 

的問題是,我用我的代碼System.IO.Directory類。 如何創建不依賴於我硬盤上的任何文件夾的測試方法。 換句話說,我該如何僞造「Directory.GetDirectories(server.Path)」的迴應? (請注意,我確實控制了我的班級中的「服務器」對象,因此我可以給任何我想要的路徑)

謝謝。

回答

0

我發現的最佳解決方案是使用Moles。代碼非常具體,並且必須做非常具體的事情。用包裝類包裝它將是多餘的。我需要包裝類的唯一原因是爲了編寫測試。痣允許我寫沒有任何包裝類的測試:)

1

你會注入一個包裝類。

public class DirectoryFetcher 
{ 
    public virtual List<string> GetDirectoriesIn(string directory) 
    { 
      return Directory.GetDirectories(directory); 
    } 
} 

然後注入是:

foreach(string directory in _directoryFetcher.GetDirectoriesIn(server.Path)) 
{ 
    // Whatever 
} 

然後,您可以莫克那傢伙在注入點(本例使用起訂量,和構造器注入):

Mock<DirectoryFetcher> mockFetcher = new Mock<DirectoryFetcher>(); 

mockFetcher.Setup(x => x.GetDirectoriesIn("SomeDirectory")).Returns(new List<string> 
{ 
    "SampleDirectory1", 
    "SampleDirectory2" 
}); 

MyObjectToTest testObj = new MyObjectToTest(mockFetcher.Object); 

// Do Test 
1

不需要調用直接使用Directory.GetDirectories(server.Path),您可以使用一個方法創建一個接口,如IDirectoryResolver,該方法接受一個路徑字符串並返回目錄列表。包含上面代碼的類將需要一個類型爲IDirectoryResolver的屬性或字段,它可以通過構造函數或setter注入。

對於您的產品代碼,您將創建一個實現IDirectoryResolver接口的新類。該類可以在其接口方法的實現中使用Directory.GetDirectories方法。

對於單元測試,您可以創建一個MockDirectoryResolver類,該類實現IDirectoryResolver(或使用模擬庫爲接口創建模擬實例)。模擬實現可以做你需要的任何事情。

0

在與外部世界進行通信時,例如文件系統,數據庫,Web服務等,在我建議之前,應該始終考慮使用類似其他類的包裝類。可測試性是一個主要論點,但更大的一個是:外面的世界發生了變化,而你無法控制它。文件夾移動,用戶權限更改,出現新的磁盤驅動器,舊的磁盤驅動器被刪除。你只想在一個地方關心那樣的東西。因此,包裝 - 我們稱之爲DirectoryResolver像安迪懷特建議ealier。

因此,包裝您的文件系統調用,提取一個接口,並在需要與文件系統進行通信的位置注入該接口。