I was testing logging with log4net today and wanted to create a unit test that verified that the method logged alright.
To verify that the logging worked I wanted to create a log appender (the MemoryAppender) and add it to the log4net configuration to be able to compare the actual logged messages with the expected ones. (The MemoryAppender has the GetEvents() and Clear() methods which works well in a unit test case).
Normally you use a configuration file (xml) to add your appenders but using configuration files in a unit test is not quite the optimal solution. So how could I set it in runtime in my test method. After a bit of testing and reading (I wonder why the testing and reading always seem to be in that order? (for me anyway) Shouldn't you start reading about the theory before you start coding and testing? ;)
I found some tips using the Hierarchy class to access the root level logger and add append the MemoryAppender there.
The important steps where to set the Configured property of the Hierarchy and call the RaiseConfigurationChanged() method to actually utilize the configuration changes.
Here is a complete example.
//First create and configure the appenderNow we have prepared the logging for the root (all log events) and directed it to the memoryAppender.
MemoryAppender memoryAppender = new MemoryAppender();
memoryAppender.Name = "MyAppender";
//Notify the appender on the configuration changes
//Get the logger repository hierarchy.
log4net.Repository.Hierarchy.Hierarchy repository =
LogManager.GetRepository() as Hierarchy;
//and add the appender to the root level
//of the logging hierarchy
//configure the logging at the root.
repository.Root.Level = Level.All;
//mark repository as configured and
//notify that is has changed.
repository.Configured = true;
//Call the method to test (this one createsWhen we have ran the code that has produced some logging, we add assert statements to check that the code behaved as we expected.
//an info level message to the log
//stating the string "GetConfiguration()".
//use the memoryAppender to get the logged eventsThats how I did it. Does anyone has another solution that works well?
LoggingEvent events = memoryAppender.GetEvents();
//We only expect one log statement on the info level
"Incorrect number of log statements");
LoggingEvent e = events;
"Incorrect logging level");
"Incorrect log message");