Programmatically check Log4Net log
Monday, November 30th, 2009Today I needed to create unit test that checked if the NHibernate query was generated optimally.
Good thing is that, in case of an inefficient query, NHibernate puts a warning using log4net:
log.Warn( "firstResult/maxResults specified with collection fetch; applying in memory!" );
I wanted something like this:
[Test]
public void FindUsersBy_QueryWithLimit_LimitsOnSQLSide()
{
using (LogChecker logChecker
= new LogChecker("NHibernate", Level.Warn))
{
// Execute query using NHibernate
// ....
Assert.IsEmpty(logChecker.Messages);
}
}
The problem is that it’s not that easy to attach MemoryAppender for a duration of unit test to the specified logger.
Anyway here’s the code:
public class LogChecker : IDisposable
{
readonly Logger _logger;
readonly Level _previousLevel;
readonly MemoryAppender _appender = new MemoryAppender();
public LogChecker(string logName, Level levelToCheck)
{
_logger = (Logger)LogManager.GetLogger(logName).Logger;
_logger.AddAppender(_appender);
_previousLevel = _logger.Level;
_logger.Level = levelToCheck;
}
public List<string> Messages
{
get
{
return new List<loggingEvent>(_appender.GetEvents())
.ConvertAll(x => x.RenderedMessage);
}
}
public void Dispose()
{
_logger.Level = _previousLevel;
_logger.RemoveAppender(_appender);
}
};