2

我想创建一个单元测试来验证 Logger.Write 命令在我的一个 MVC 控制器中使用正确的消息执行。

我可以模拟 Logger 写入的 Listener,但我不知道如何访问存储的消息。例如,

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");

这个写入记录器的命令不会返回输入字符串或将其存储到一个参数中,以便我使用断言语句进行验证。我可以使用 Moq 验证或设置之一或 .when(无论这是什么)函数来获取记录的消息,或者至少检查它是否已执行?

最好,我想将日志条目存储到我的单元测试中的一个变量中,以便我可以断言:

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

如果有人知道这样做的策略,我将不胜感激。

4

2 回答 2

3

假设您使用的是 Entlib 5.0,那么您已经有了一个模拟点。与其直接使用 Logger.Write,不如将 LogWriter 的实例注入到您的控制器中。然后,您可以在测试中模拟 LogWriter 对象。

于 2012-06-28T22:44:08.247 回答
0

您希望使用回调作为将 Write 方法中的输入返回到单元测试的一种方式。

因为 Loggers 是静态的,所以您必须包装对这些静态方法的调用才能在测试中使用 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 );
}

请注意,我使用的是最小起订量版本 4.0.10827.0。

我希望这有帮助!

于 2012-06-28T13:33:01.623 回答