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