C# Xunit,当预期异常被引发时Assert.Throws失败

7

编辑:这里有一个类似的问题,但解决方案只是提供了一些变通方法,并没有深入探讨问题的原因或如何解决。这个问题可能仍然是重复的。

编辑2:事实证明,这个问题仅在调试期间发生,尽管之前没有发生。将(TCheck)null替换为null as TCheck后,测试在运行时通过,但在调试时会抛出异常。

原始帖子:我在单元测试中有一个方法,看起来像这样

internal void EqualityAssert<TCheck, TEquatable>(TEquatable item, ... ) 
    where TCheck : class, IEquatable<TEquatable>, TEquatable
{

    // Various equality assertions that are passing
    // ...

    // A == null       
    Assert.Throws<NullReferenceException>(
    () => ((IEquatable<TEquatable>)item).Equals((TCheck)null));            
}

该方法被各种单元测试调用,每个测试都因为在预期位置遇到 "Unhandled NullReferenceException" 错误而失败。

之前 Assert.Throws 对我来说是正常工作的,但我一直没有找出是什么改变导致了它的破裂。


你尝试过调试你的测试了吗? - rclocher3
@StephenRoss 这并没有解决问题,我仍然在Equals实现中遇到了异常,正是预料的地方。 - Kelson Ball
@rclocher3 或许我误解了你的问题..是的,我正在一步一步地检查测试并检查值,一切都符合预期。你是否在问有关更具体的调试方法? - Kelson Ball
不,我只是在回忆一次我的测试失败了,因为有一个未捕获的异常,我以为这是预期的,但事实证明异常是在代码的其他地方被抛出的。祝你好运。 - rclocher3
((IEquatable<TEquatable>)item).Equals((TCheck)null)的值分配给一个临时变量是否可以防止JITter优化掉它?在你的尝试中,你最终会调用Object.Equals(Object)而不是IEquatable的方法吗?请确保尽可能向我们展示你的实际代码... - Ruben Bartelink
显示剩余2条评论
2个回答

6
最好使用这种模式:
[Fact]
public void Divide_TwoNumbers_ExpectException()
{
    var sut = new Calculator();
    var exception = Record.Exception(() => sut.Divide(10, 0));
    Assert.IsType(typeof(DivideByZeroException), exception);
}

3
为什么更好?(并非说它不好,但这会改善答案) - ediblecode
1
使用异步方法:Record.Exception(()=>GetSomeAsync().GetAwaiter().GetResult()); - rnrneverdies
2
这个答案是从 https://www.richard-banks.org/2015/07/stop-using-assertthrows-in-your-bdd.html 复制并粘贴的。你应该将其链接为来源。 - Anton Kalcik
xUnit Assert建议您使用Assert.IsType<T>(exception)而不是使用typeof()表达式。 - loganjones16
这段代码已经过时了,新的方式是: Assert.IsType<NullReferenceException>(exception.Result); 请更新您的代码。 - Sharif Yazdian

0
你抛出了异常,但你应该处理它。请查看下面的代码。你可以根据我的示例修改你的代码。
var message = FakeRequestBuilder.CreateSettlementFileMessage();

var warning = Assert.Throws<ExF.Core.Exception.IntegrationValidationException>(
                () => createSettlementFileHandler.Handle(message));

Assert.Equal(warning.ErrorCode, -1);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接