单元测试和Log4net

Par*_*Par 13 asp.net unit-testing asp.net-mvc-3

我在我的控制器中测试一个动作的单元测试,动作写入log4net.

当我运行我的动作时效果很好 - 写入log4net.

但是,当我运行单元测试时 - 该操作不会写入log4net但不会抛出任何异常.

有没有人有办法解决吗?

Rhy*_*ysC 22

// ARRANGE
var memoryAppender = new MemoryAppender();
BasicConfigurator.Configure(memoryAppender);

// ACT
_sut.DoWhatever();

// ASSERT - using xunit - change the expression to fit your purposes
Assert.True(memoryAppender.GetEvents().Any(le => le.Level == Level.Warn), "Expected warning messages in the logs");
Run Code Online (Sandbox Code Playgroud)

你并不需要使用日志接口(如果你不想)在间接的另一层补充.我已经使用抽象的方式多年了,但现在我正在使用MemoryAppender,因为它正在测试实际发生的事情.每次测试后,请确保.Clear()appender.


Jay*_*Jay 8

Log4net不会抛出异常:http://logging.apache.org/log4net/release/faq.html

在单元测试中写入磁盘或数据库中的日志会适得其反; 重点是自动化.每次运行测试时都不必检查日志.

如果您确实需要验证是否已对某些内容进行了调用,则应该模拟该ILog接口并声明调用了相应的方法.

如果您使用的是模拟框架,这是微不足道的.如果不是,则可以创建一个TestLogger实现或部分实现的类,ILog并公开显示给定方法调用次数的额外属性.您的断言将检查方法是否按预期调用.

以下是要测试的类的示例:

  public class MyComponent
  {
    private readonly ILog _log;

    public MyComponent(ILog log)
    {
      _log = log;
    }

    public string DoSomething(int arg)
    {
      _log.InfoFormat("Argument was [{0}]", arg);
      return arg.ToString();
    }
  }
Run Code Online (Sandbox Code Playgroud)

和测试(使用Rhino.Mocks来模拟ILog):

[TestClass]
  public class MyComponentTests
  {
    [TestMethod]
    public void DoSomethingTest()
    {
      var logger = MockRepository.GenerateStub<ILog>();
      var component = new MyComponent(logger);

      var result = component.DoSomething(8);

      Assert.AreEqual("8", result);
      logger.AssertWasCalled(l => l.InfoFormat(Arg<string>.Is.Anything, Arg<int>.Is.Equal(8)));
    }
  }
Run Code Online (Sandbox Code Playgroud)

  • @bryanbcook在某种程度上,我同意,但有很多次这是有效的.就在今天,我必须实现客户端的要求,以针对Web服务记录每个身份验证.围绕验证方法的单元测试是否包含调用记录器的断言是否有效?同样,我不认为任何实际的日志记录应该在单元测试的上下文中发生,只是被测试的方法正在做它应该对其协作者应该做的事情. (3认同)
  • 除非应用程序的目的是生成日志,否则编写单元测试来验证日志记录是否发生只是将实现细节泄漏到测试中。测试行为,而不是实现。 (2认同)

Dar*_*ker 6

尝试添加:

[assembly: log4net.Config.XmlConfigurator()]
Run Code Online (Sandbox Code Playgroud)

AssemblyInfo.cs(或init log4net任何其他方式).在这里找到这个答案


Ill*_*ati 1

这是您的 log4net 配置。现在它可能位于 web/bin 中的 web.config 或 log4net.config 文件中。您必须将其放置在一个公共位置,并使其可以被 Web 应用程序和测试发现。或者你必须将它放入你的unittest.project=>app.config 文件中。但如果你有很多测试项目,它就会在很多地方重复。因此,理想的做法是将其放在一个共同的地方。