C# 如何测试代码在不改变堆栈跟踪的情况下重新抛出异常?

C# 如何测试代码在不改变堆栈跟踪的情况下重新抛出异常?,c#,xunit,C#,Xunit,我有一段代码,作为中间件,负责在执行任意代码之前和之后记录时间戳,以及捕获它可能抛出的任何异常,记录它们并重新刷新它们。我一直在尝试设计一个测试,以确保中间件不会影响原始代码抛出的堆栈跟踪 我已经试过了 [Fact] public async Task The_Middleware_Must_Rethrow_Any_Exception_Thrown_By_The_Next_Middleware() { var middleware = new ErrorMiddleware();

我有一段代码,作为中间件,负责在执行任意代码之前和之后记录时间戳,以及捕获它可能抛出的任何异常,记录它们并重新刷新它们。我一直在尝试设计一个测试,以确保中间件不会影响原始代码抛出的堆栈跟踪

我已经试过了

[Fact]
public async Task The_Middleware_Must_Rethrow_Any_Exception_Thrown_By_The_Next_Middleware()
{
    var middleware = new ErrorMiddleware();
    _testSubject = new RequestLoggerMiddleware(middleware);

    try
    {
        await _testSubject.Invoke(_mockContext.Object);
    } catch (Exception ex)
    {
        Assert.Same(ex, middleware.ThrownException);
        Assert.Equal(ex.StackTrace, middleware.ThrownException.StackTrace);
        return;
    }

    Assert.True(false, "The middleware did not rethrow the exception");
}

private class ErrorMiddleware : OwinMiddleware
{
    public Exception ThrownException { get; }

    public ErrorMiddleware() : base(null) 
    {
        ThrownException = new Exception(TestExceptionMessage);    
    }

    public override Task Invoke(IOwinContext context)
    {
        throw ThrownException;
    }
}

它一开始似乎很有效,但如果我使用
RequestLoggerMiddleware
run
throw-excatch(Exception ex)
块(在过程中重写stacktrace)上的code>测试仍然会通过,即使它根本不应该通过。

可能是异常被包装在
\u testSubject
中的某个地方。如果此包装不可接受,则可以检查引发异常的特定方法,如:

    Assert.Equal(
            ex.TargetSite, 
            typeof(ErrorMiddleware).GetMethod(nameof(ErrorMiddleware.Invoke), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));

可能是异常被包装在
\u testSubject
中的某个地方。如果此包装不可接受,则可以检查引发异常的特定方法,如:

    Assert.Equal(
            ex.TargetSite, 
            typeof(ErrorMiddleware).GetMethod(nameof(ErrorMiddleware.Invoke), BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));

这似乎是一个静态分析器应该捕捉到的东西。这是一辆马车,经常撞车,但这是发现类似问题的好方法。下面是一些分析错误处理异常的代码的其他内容。我更喜欢analyzer方法,因为a)谁想为此编写测试,b)如果我们需要检查这一点,它可能在我们的代码中。我现在就要试试这个。只做
抛出(而不是
抛出ThrownException;
)不为您工作?看到这个:@trailmax你可以做
抛出在catch块中。但这并不是一个简单的问题。另一种看待这个问题的方法是质疑我们是否需要测试它。已知
throw
vs
throw ex
的行为。是否需要测试来确认他们的行为?我们为我们能控制的东西编写单元测试。如果测试失败,我们将无法做任何事情来纠正它。这似乎是一个静态分析器应该捕捉的东西。这是一个扩展。这是一辆马车,经常撞车,但这是发现类似问题的好方法。下面是一些分析错误处理异常的代码的其他内容。我更喜欢analyzer方法,因为a)谁想为此编写测试,b)如果我们需要检查这一点,它可能在我们的代码中。我现在就要试试这个。只做
抛出(而不是
抛出ThrownException;
)不为您工作?看到这个:@trailmax你可以做
抛出在catch块中。但这并不是一个简单的问题。另一种看待这个问题的方法是质疑我们是否需要测试它。已知
throw
vs
throw ex
的行为。是否需要测试来确认他们的行为?我们为我们能控制的东西编写单元测试。如果测试失败,我们将无法做任何事情来纠正它。@Machinarius,好吧,那么我再做一个猜测。如果中间件包装了异常,该怎么办。我已经更新了我的answer@Machinarius,好吧,那我再猜一次。如果中间件包装了异常,该怎么办。我已经更新了我的答案