2012-06-28 94 views
2

我想創建一個單元測試,驗證Logger.Write命令是在我的一個MVC控制器中使用正確的消息執行的。如何使用Moq驗證企業庫日誌記錄?

我可以模擬記錄器寫入的監聽器,但我不知道如何訪問存儲的消息。例如,

var mockListener = new Mock<MyTraceListener>(); 
// the .Write method is void so I can't use .Returns() on my mock 
mockListener.Setup(listener => listener.Write(It.IsAny<string>())) 

MyController controller = new MyController(); 
MyController.Index(); 

//然後索引方法調用下面Logger.Write()到寫入MyTraceListener類別:

Logger.Write("test message", "MyCategory"); 

這寫命令記錄器不返回輸入字符串或將其存儲到參數中以供我使用Assertion語句進行驗證。我可以使用Moq驗證或設置之一,或.when(無論這是什麼)函數來獲取記錄的消息,或者至少檢查它是否被執行?

最好,我想日誌條目到一個變量保存在我的單元測試,所以我可以斷言這一點:

Assert.AreEqual(loggedMessage, "test message"); 

如果任何人的策略要做到這一點我將不勝感激的人知道。

回答

0

您想使用回調作爲從Write方法獲取輸入回到單元測試的方法。

因爲記錄器是靜態的,所以您必須將調用包裝爲這些靜態方法才能在測試中使用Moq。下面的示例類應該是你需要做的所有事情來做到這一點。您還必須更新代碼才能使用包裝器,這可能會很痛苦。

這是一個樣本測試和類結構來實現這一點。

public class Logger 
{ 
    public virtual void Write(string message, string category) 
    { 
     Loggers.Write(message, category); 
    } 
} 

[TestMethod] 
public void SampleTest() 
{ 
    string input = string.Empty; 

    var mockLogger = new Mock<Logger>(); 
    mockLogger.Setup(l => l.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string message, string category) => input = message); 


    mockLogger.Object.Write("test", "category"); 

    Assert.AreEqual("test", input); 
} 

請注意我正在使用Moq版本4.0.10827.0。

我希望這有助於!

+0

這是有幫助的。我可以配置它來檢測我的控制器源代碼中的Logger.Write命令,而不是測試方法中的mockLogger? – barnone

+0

如果我明白你的要求是正確的,你需要設置模擬記錄器並將它作爲依賴注入到控制器中,以便按照你想要的方式進行連接。 –

+0

這就是我希望避免的。我相當缺乏經驗,這對我來說似乎不是一個好的編碼習慣。 – barnone

3

假設您使用的是Entlib 5.0,那麼您已經有了一個模擬點。而不是直接使用Logger.Write,而是將LogWriter的一個實例注入到控制器中。然後,您可以在測試中嘲笑LogWriter對象。

相關問題