Search code examples
c#xunitvstestfluent-assertions

Formatting Exception displayed when a unit test fails (xunit , C#)


I am using .Net6 + Xunit + Fluent Assertions and am trying to format the exception display that is output to console when an exception is encountered. (what I really want to see is the Data property on the Exception)

In my program itself I add a handler to AppDomain.UnhandledException, but in the tests, this does not change the output at all.

I've looked for an alternative way of setting a custom formatter for exceptions, but I haven't found a way, neither in Fluent Assertions nor Xunit.

Is there any way to format exception output in tests?


Solution

  • I found a way to do this through the library XunitContext (nuget)

    Sample code:

    public static class GlobalSetup {
        [ System.Runtime.CompilerServices.ModuleInitializer ]
        public static void Setup( ) {
            XunitContext.EnableExceptionCapture();
        }
    }
    
    public class TestExceptionSample :
        XunitContextBase {
        [ Fact ]
        public void TestExceptionUsage( ) {
            // This test will fail
            Assert.False( true );
        }
    
        [ Fact ]
        public void TestExceptionExceptionUsage( ) {
            // Exception is thrown
            Exception exception = new Exception( "MY EXCEPTION" );
            exception.Data.Add( "Key1", "Value1" );
            throw exception;
        }
    
        public TestExceptionSample( ITestOutputHelper output ) :
            base( output ) { }
    
        public override void Dispose( ) {
            var theExceptionThrownByTest = Context.TestException;
            var testDisplayName          = Context.Test.DisplayName;
            var testCase                 = Context.Test.TestCase;
            Output.WriteLine( "Handling Exception" );
            if ( Context.TestException?.Data.Count > 0 ) {
                foreach ( var key in Context.TestException.Data.Keys ) {
                    Output.WriteLine( $"{key} => {Context.TestException.Data[ key ]}" );
                }
            }
        }
    }
    

    Outputs:

     Failed Tests.TestExceptionSample.TestExceptionUsage [4 ms]
      Error Message:
       Assert.False() Failure
    Expected: False
    Actual:   True
      Stack Trace:
         at Tests.TestExceptionSample.TestExceptionUsage() in /Tests.cs:line 108
      Standard Output Messages:
     Handling Exception
    
    
      Failed Tests.TestExceptionSample.TestExceptionExceptionUsage [< 1 ms]
      Error Message:
       System.Exception : MY EXCEPTION
      Stack Trace:
         at Tests.TestExceptionSample.TestExceptionExceptionUsage() in /Tests.cs:line 115
      Standard Output Messages:
     Handling Exception
     Key1 => Value1
    
    
    
    Test Run Failed.
    Total tests: 2
         Failed: 2
     Total time: 1.4345 Seconds