views:

1283

answers:

3

Hi.

I have a component that uses log4net. I want to create unit tests, that validate that certain error conditions result in the correct logging.

I was thinking that the best way to do this is to create an ILogAppender implementation, for example a mock. I would then add the log appender to log4net during test setup, inspect what was written during test validation, and remove it again during test teardown.

Is this possible?

+1  A: 

The following code was originally found on the apache mailing list archives and should solve the problem of adding and removing log4net appenders in code

/// <summary>
/// dataLog
/// </summary>
protected static readonly IDeviceCommunicationsLog dataLog =
DeviceCommunicationsLogManager.GetLogger("LIS3.Data");


Each connection adds and removes a file appender programmatically:

/// <summary>
/// add connection specific appender
/// </summary>
void AddAppender()
{
    // check if logging is endabled
    if( this.IsLoggingEnabled() )
    {
     try
     {
      // get the interface
      IAppenderAttachable connectionAppender = (IAppenderAttachable)this.DataLog.Logger;
      // need some application configuration settings
      NameValueCollection appSettings = ConfigurationSettings.AppSettings;
      // get the layout string
      string log4netLayoutString = appSettings["log4net.LIS3.LayoutString"];
      if( log4netLayoutString == null )
      {
       // use default setting
       log4netLayoutString = "%d [%x]%n   %m%n  %P MessageData}%n%n";
      }
      // get logging path
      string log4netPath = appSettings["log4net.Path"];
      if( log4netPath == null )
      {
       // use default path
       log4netPath = ".\\";
      }
      // create the appender
      this.rollingFileAppender = new RollingFileAppender();
      // setup the appender
      this.rollingFileAppender.MaxFileSize = 10000000;
      this.rollingFileAppender.MaxSizeRollBackups = 2;
      this.rollingFileAppender.RollingStyle =   RollingFileAppender.RollingMode.Size;
      this.rollingFileAppender.StaticLogFileName = true;
      string appenderPath = LogSourceName + ".log";
      // log source name may have a colon - if soreplace with underscore
      appenderPath = appenderPath.Replace( ':', '_' );
      // now add to log4net path
      appenderPath = Path.Combine( log4netPath, appenderPath );
      // update file property of appender
      this.rollingFileAppender.File = appenderPath;
      // add the layout
      PatternLayout patternLayout = new PatternLayout(   log4netLayoutString );
      this.rollingFileAppender.Layout = patternLayout;
      // add the filter for the log source
      NDCFilter sourceFilter = new NDCFilter();
      sourceFilter.StringToMatch = this.LogSourceName;
      this.rollingFileAppender.AddFilter( sourceFilter);
      // now add the deny all filter to end of the chain
      DenyAllFilter denyAllFilter = new DenyAllFilter();
      this.rollingFileAppender.AddFilter( denyAllFilter );
      // activate the options
      this.rollingFileAppender.ActivateOptions();
      // add the appender
      connectionAppender.AddAppender( this.rollingFileAppender );
     }
     catch( Exception x )
     {
      this.ErrorLog.Error( "Error creating LIS3 data log appender for " + LogSourceName, x );
     }
    }
}
/// <summary>
/// remove connection specific appender
/// </summary>
void RemoveAppender()
{
    // check if we have one
    if( this.rollingFileAppender != null )
    {
     // cast to required interface
     IAppenderAttachable connectionAppender = (IAppenderAttachable)this.DataLog.Logger;
     // remove the appendier
     connectionAppender.RemoveAppender( rollingFileAppender );
     // set to null
     this.rollingFileAppender = null;
    }
}
armannvg
+2  A: 

I have been using the BasicConfigurator configured with a MemoryAppender. This appender lets you get to the in-memory messages logged during your test.

Peter Lillevold
I finally got to implementing this, and it solves the problem very nicely
Pete
+1  A: 

Recently I did something similar: Programmatically check Log4Net log.

Pawel Lesnikowski