2012-09-11 54 views
0

我有一個使用StreamWriter寫入文件的類。嘲笑StreamWriter /確定何時模擬

public void CreateLog(string errorLogFilePath, StringBuilder errorLogBuilder, string errorMessage) 
{ 
    using (StreamWriter sw = new StreamWriter(errorLogFilePath, true) 
    { 
     errorLogBuilder.Apend("An error was discovered."); 
     //.... 
     sw.Write(errorLogBuilder.ToString()); 
    } 
} 

[問題]

1:是否有可能檢查.WRITE()方法被調用?

2:我是否需要在StreamWriter內部包裝MemoryStream才能測試它,而無需實際訪問硬盤驅動器。一個StreamWriters構造函數接受一個流,但它聲明以下內容+ UTF-8編碼是否會影響這個?

使用UTF-8編碼和默認緩衝區大小爲指定流初始化StreamWriter類的新實例。

3:如何確定一個類是否實際訪問hd並因此需要被模擬? (對不起,如果這最後一個問題聽起來很愚蠢,但我真的有點困惑於此)。

回答

3

讓方法寫入TextWriter而不是StreamWriter。然後通過傳遞一個模擬TextWriter來測試該方法。在「真實」代碼中,當然,您將傳入使用new StreamWriter(errorLogFilePath, true)創建的StreamWriter。

我們得到以下問題的答案:

  1. 沒有
  2. 你一般不能確定,如果沒有反編譯其代碼。

更詳細一點:

重構方法爲兩種方法:

public void CreateLog(string errorLogFilePath, StringBuilder errorLogBuilder, string errorMessage) 
{ 
    using (StreamWriter sw = new StreamWriter(errorLogFilePath, true) 
    { 
     CreateLog(sw, errorLogBuilder, errorMessage); 
    } 
} 

public void CreateLog(TextWriter writer, StringBuilder errorLogBuilder, string errorMessage) 
{ 
    errorLogBuilder.Apend("An error was discovered."); 
    //.... 
    writer.Write(errorLogBuilder.ToString()); 
} 

測試,以確保它調用與適當構造的StreamWriter的第二種方法中,第一種方法。測試第二種方法以確保它在傳遞的TextWriter上調用Write,並帶有適當的參數。現在你已經提取了硬盤上的依賴關係。您的測試不使用硬盤,但您正在測試所有內容。

+0

感謝您的回覆。關於(3),我指的是MemoryStream,StreamReader,StreamWriter等。你如何知道哪一個實際訪問HD?大約一個月前,我問了一個類似的問題,Jon Skeet說我可以在StreamReader中包裝一個memoryStream。爲什麼我不能在這裏做同樣的事情? –

+0

@HansRudel你確實可以在這裏做同樣的事情(順便提一下,StreamWriter的構造函數可以讓你提供一個流*和*指定編碼),但是我發現這種方法更簡單。使用內存流創建StreamWriter將允許您在沒有模擬框架的情況下編寫測試,但是您使用了'moq'標記,那麼爲什麼不只是模擬抽象類呢? – phoog

+0

@HansRudel我忘記了地址(3)。訪問HD的類是FileStream。當您將文件路徑而不是流傳遞給StreamWriter構造函數時,StreamWriter會創建一個FileStream。如果你有一個StreamWriter並想知道它正在寫什麼(文件,內存,其他),你應該能夠通過檢查它的BaseStream屬性來確定它。 – phoog

1

一般來說,你可以:

使用以及測試日誌庫(如NLOG,MS記錄應用程序塊),省得你深化發展和維護自己。

將您的日誌邏輯(或調用消息框的代碼,打開文件對話框等)重構爲帶有其接口的服務。通過這種方式,您可以拆分測試策略:

  • 測試loggin服務的使用者時:模擬日誌記錄界面以確保調用日誌方法。這將確保日誌記錄服務的消費者在測試日誌記錄服務實現時正確調用日誌記錄服務
  • ,只需確保預期的輸出匹配給定的輸入:如果要將「FOO」寫入條形圖。登錄,有效地叫

IE:

// arrrange 
File.Delete("bar.log") 

// act 
CreateLog("bar.log", errorLogBuilder, "FOO") 

// assert 
Assert.IsTrue(File.Exists("bar.log")) 
Assert.IsTrue(File.ReadAllLines("bar.log").First() == "FOO") 

點是確保該組件被調用,通過嘲諷來完成。 然後您可以檢查組件是否按預期工作。