私のクラスには次の行があります:
private static readonly ILog log = LogManager.GetLogger(typeof(Prim));
単体テストに行くと、moq ロガーをこのインターフェイスに挿入できないため、ログ呼び出しをカウントできます。
これを行う方法はありますか?Log4net は、ロガーに対して静的な読み取り専用パターンを推奨しています。それを処理する最良の方法は何ですか?
私のクラスには次の行があります:
private static readonly ILog log = LogManager.GetLogger(typeof(Prim));
単体テストに行くと、moq ロガーをこのインターフェイスに挿入できないため、ログ呼び出しをカウントできます。
これを行う方法はありますか?Log4net は、ロガーに対して静的な読み取り専用パターンを推奨しています。それを処理する最良の方法は何ですか?
log4net はこのパターンを推奨していますが、クラス外でロガーをインスタンス化して注入することを妨げるものは何もありません。ほとんどの IoC は、1 つの同じインスタンスを注入するように構成できます。そうすれば、単体テストにモックを挿入できます。
タイプごとに常に 1 つの同じロガー インスタンスを返す 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());
}
}
}