我的课上有这行:

private static readonly ILog log = LogManager.GetLogger(typeof(Prim));

当我进行单元测试时,我无法将Moq记录器注入(inject)此界面,因此我可以计算日志调用数。

有没有办法做到这一点? Log4net建议记录器使用静态只读模式。最好的处理方法是什么?

最佳答案

尽管log4net推荐这种模式,但没有什么可以阻止您在类之外实例化logger并将其注入(inject)。大多数IoC可以配置为注入(inject)一个实例。这样,对于单元测试,您可以注入(inject)一个模拟。

我建议使用LogManager.GetLogger的包装器,该包装器对于每种类型总是返回一个相同的记录器实例:

namespace StackOverflowExample.Moq
{
    public interface ILogCreator
    {
        ILog GetTypeLogger<T>() where T : class;
    }

    public class LogCreator : ILogCreator
    {
        private static readonly IDictionary<Type, ILog> loggers = new Dictionary<Type, ILog>();
        private static readonly object lockObject;

        public ILog GetTypeLogger<T>() where T : class
        {
            var loggerType = typeof (T);
            if (loggers.ContainsKey(loggerType))
            {
                return loggers[typeof (T)];
            }

            lock (lockObject)
            {
                if (loggers.ContainsKey(loggerType))
                {
                    return loggers[typeof(T)];
                }
                var logger = LogManager.GetLogger(loggerType);
                loggers[loggerType] = logger;
                return logger;
            }
        }
    }

    public class ClassWithLogger
    {
        private readonly ILog logger;
        public ClassWithLogger(ILogCreator logCreator)
        {
            logger = logCreator.GetTypeLogger<ClassWithLogger>();
        }

        public void DoSomething()
        {
            logger.Debug("called");
        }
    }

    [TestFixture]
    public class Log4Net
    {
        [Test]
        public void DoSomething_should_write_in_debug_logger()
        {
            //arrange
            var logger = new Mock<ILog>();
            var loggerCreator = Mock.Of<ILogCreator>(
                c =>
                c.GetTypeLogger<ClassWithLogger>() == logger.Object);

            var sut = new ClassWithLogger(loggerCreator);

            //act
            sut.DoSomething();

            //assert
            logger.Verify(l=>l.Debug("called"), Times.Once());
        }
    }
}

关于C#静态只读log4net记录器,是否可以在单元测试中更改记录器?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16796690/

10-11 08:08