我想创建一个单元测试,验证Logger.Write命令是否在我的一个MVC控制器中使用正确的消息执行。
我可以模拟Logger写入的监听器,但我不知道如何到达存储的消息。例如,
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();
//然后Index方法将以下Logger.Write()调用到写入MyTraceListener的类别:
Logger.Write("test message", "MyCategory");
对记录器的这个写命令不返回输入字符串或将其存储到参数中,以便我使用Assertion语句进行验证。我可以使用Moq验证或设置之一,或者使用.when(不管是什么)函数来获取记录的消息,或者至少检查它是否已执行?
最好,我想将日志条目存储到单元测试中的变量中,以便我可以断言:
Assert.AreEqual(loggedMessage, "test message");
如果有人知道这样做的策略,我将非常感激。
答案 0 :(得分:3)
假设您正在使用Entlib 5.0,那么您已经有了一个模拟点。而不是直接使用Logger.Write,而是将LogWriter实例注入您的控制器。然后,您可以在测试中模拟LogWriter对象。
答案 1 :(得分:0)
您希望使用Callback作为将Write方法的输入返回到单元测试的方法。
因为Logger是静态的,所以你必须将调用包装到那些静态方法中,以便在测试中使用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版。
我希望这有帮助!