[c#] 你如何嘲笑C#中的文件系統進行單元測試?



5 Answers

這個虛構的庫現在存在,有一個用於System.IO.Abstractions的NuGet包,它抽像出System.IO命名空間。

還有一套測試助手System.IO.Abstractions.TestingHelpers,它在撰寫本文時僅部分實施,但是它是一個非常好的起點。

Question

是否有任何庫或方法在C#中編寫文件系統來編寫單元測試? 在我目前的情況下,我有方法檢查某個文件是否存在並讀取創建日期。 未來我可能需要更多。




您可以使用Microsoft Fakes來做到這一點,而無需更改您的代碼庫,因為它已經被凍結。

首先為System.dll 生成偽裝 - 或者其他任何包,然後模擬預期的回報,如下所示:

using Microsoft.QualityTools.Testing.Fakes;
...
using (ShimsContext.Create())
{
     System.IO.Fakes.ShimFile.ExistsString = (p) => true;
     System.IO.Fakes.ShimFile.ReadAllTextString = (p) => "your file content";

      //Your methods to test
}



我會和Jamie Ide一起回應。 不要試圖嘲笑你沒有寫的東西。 將會有你不知道的所有依賴關係 - 密封類,非虛擬方法等。

另一種方法是用可嘲弄的東西來包裝應用程序的方法。 例如創建一個名為FileWrapper的類,該類允許訪問File方法,但是您可以將其模擬出來。




在測試中嘲笑文件系統是很困難的,因為.NET文件API並不是真正基於可能被嘲笑的接口或可擴展類。

但是,如果你有自己的功能層來訪問文件系統,你可以在單元測試中嘲笑它。

作為嘲笑的替代方法,可以考慮將您需要的文件夾和文件作為測試設置的一部分,並在拆卸方法中刪除它們。




回答你的具體問題:不,沒有庫允許你模擬文件I / O調用(我知道的)。 這意味著“正確地”單元測試你的類型將要求你在定義類型時考慮到這個限制。

關於我如何定義“適當”單元測試的快速說明。 我相信單元測試應該確認你得到了預期的輸出(是一個例外,調用一個方法等)提供了已知的輸入。 這允許您將單元測試條件設置為一組輸入和/或輸入狀態。 我發現這樣做的最好方式是使用基於接口的服務和依賴注入,以便通過通過構造函數或屬性傳遞的接口提供類型外部的每個責任。

所以,考慮到這一點,回到你的問題。 我通過創建一個IFileSystemService接口和一個FileSystemService實現來嘲笑文件系統調用,該實現只是mscorlib文件系統方法的一個外觀。 我的代碼然後使用IFileSystemService而不是mscorlib類型。 這允許我在應用程序運行時插入標準FileSystemService ,或者在單元測試中模擬IFileSystemService 。 無論應用程序如何運行,應用程序代碼都是相同的,但底層基礎結構允許輕鬆測試代碼。

我會承認,使用mscorlib文件系統對象的包裝是一件很痛苦的事情,但在這些特定的場景中,測試變得如此簡單和可靠,值得額外的工作。







Related