单元测试失败时显示格式化异常(xunit,C#)

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

我正在使用 .Net6 + Xunit + Fluent Assertions 并尝试格式化异常显示,当遇到异常时输出到控制台。 (我真正想看到的是Exception上的Data属性)

在我的程序本身中,我向 AppDomain.UnhandledException 添加了一个处理程序,但在测试中,这根本不会改变输出。

我一直在寻找为异常设置自定义格式化程序的替代方法,但我还没有找到方法,无论是在 Fluent Assertions 还是在 Xunit 中。

有什么方法可以在测试中格式化异常输出吗?

在你的测试中Class,在构造函数中

    private readonly ITestOutputHelper _outputHelper;

    public TestCaseClass(ITestOutputHelper outputHelper)
    {
        _outputHelper = outputHelper;
    }

然后(这不是我推荐的)将您的行为包装起来并在 try/catch 中声明部分代码。捕获异常,使用输出助手记录数据字段,然后重新抛出。

try 
{ 
    // Act

   // Assert
} 
catch(Exception ex) 
{ 
    _outputHelper.WriteLine(ex.Data)
    throw;
}

这不是要求,但你应该考虑登录你的实际代码,你可以将大多数日志记录框架连接到 xUnit 的输出助手,并让你的应用程序非常愉快地记录到测试控制台。

我通过图书馆找到了一种方法 XunitContext (nuget)

示例代码:

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 ]}" );
            }
        }
    }
}

输出:

 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