Reputation: 1547
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?
Upvotes: 1
Views: 1365
Reputation: 1547
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
Upvotes: 1
Reputation: 107
In your Test Class, in the constructor
private readonly ITestOutputHelper _outputHelper;
public TestCaseClass(ITestOutputHelper outputHelper)
{
_outputHelper = outputHelper;
}
Then (and this isn't something i'd reccomend) wrap your act and assert portions of code in a try/catch. Catch the excpetion, log the Data field using the Output Helper and then rethrow.
try
{
// Act
// Assert
}
catch(Exception ex)
{
_outputHelper.WriteLine(ex.Data)
throw;
}
This wasn't asked, but you should consider logging in your actual code, you can wire up most logging frameworks to the output helper of xUnit and have your application log to the test console quite happily.
Upvotes: 0