Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture log4net output in xunit2

I've read http://xunit.github.io/docs/capturing-output.html and it seems to apply to making my test output specific message during the test running but I would really like to be able to capture the log4net output that is already integrated into the classes I am testing.

In the past i have set up log4net to use a TraceLogger and the test framework was able to associate the output with the test. (different testing framework). How can I somehow associate log4net output to the Xunit IOutputHelper?

like image 250
Jeff Martin Avatar asked Mar 17 '23 10:03

Jeff Martin


1 Answers

This was the answer i came up with

This is a class I can make my test class inherit from:

   public class LogOutputTester:IDisposable
    {
        private readonly IAppenderAttachable _attachable;
        private TestOutputAppender _appender;

        protected LogOutputTester(ITestOutputHelper output)
        {
            log4net.Config.XmlConfigurator.Configure(); 
            var root = ((log4net.Repository.Hierarchy.Hierarchy)LogManager.GetRepository()).Root;
            _attachable = root;

            _appender = new TestOutputAppender(output);
            if (_attachable != null)
                _attachable.AddAppender(_appender);
        }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            _attachable.RemoveAppender(_appender);
        }
    }

this is a custom Appender I made referenced in the above helper:

 public class TestOutputAppender : AppenderSkeleton
    {
        private readonly ITestOutputHelper _xunitTestOutputHelper;

        public TestOutputAppender(ITestOutputHelper xunitTestOutputHelper)
        {
            _xunitTestOutputHelper = xunitTestOutputHelper;
            Name = "TestOutputAppender";
            Layout = new PatternLayout("%-5p %d %5rms %-22.22c{1} %-18.18M - %m%n");
        }

        protected override void Append(LoggingEvent loggingEvent)
        {
            _xunitTestOutputHelper.WriteLine(RenderLoggingEvent(loggingEvent));
        }
    }

This could be customized more to take a custom layout or whatever...

Finally - i just make my test class inherit from this helper:

   public class MyTestClass:LogOutputTester
    {
        public EdgeClientTests(ITestOutputHelper output):base(output)
        {
        }
    ...

You could give your tests direct access to the output object too...

like image 146
Jeff Martin Avatar answered Mar 19 '23 07:03

Jeff Martin