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?
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...