You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Assert.Multiple会“记住”已捕获的断言失败?

问题

为什么第一个代码块中已捕获的AssertionException会被Assert.Multiple再次捕获?直接调用Assert.True(true)不会抛出异常,当前使用.NET 6.0。

示例代码

using NUnit.Framework;

namespace Sandbox {
    public class Program {
        public static void Main(string[] args) {
            try {
                Assert.Fail("Fail!");
            } catch (Exception e) {
                Console.WriteLine("Expected exception");
            }

            try {
                Assert.Multiple(() => { Assert.True(true); });
            } catch (Exception e) {
                Console.WriteLine("Unexpected exception: " + e.Message);
            }
        }
    }
}

运行输出

Expected exception

Unexpected exception: Fail!

原因解析

这是因为NUnit的断言机制依赖线程本地的断言上下文跟踪断言结果。第一个Assert.Fail抛出的异常虽然被捕获,但NUnit内部的线程上下文并未重置,依然保留着这次失败的断言记录。

当调用Assert.Multiple时,它会先检查当前线程上下文里的所有历史断言结果,一旦发现未清理的失败记录,就会抛出包含该失败信息的异常。而直接调用Assert.True(true)时,单个断言只会验证自身逻辑是否通过,不会检查上下文里的历史记录,因此不会触发异常。

如果是在NUnit测试类的测试方法中执行这段逻辑,NUnit会在每个测试方法执行前后自动重置线程上下文,就不会出现这种问题。而在控制台程序的Main方法中,没有NUnit的测试生命周期管理,上下文不会自动重置,才会出现这种“旧异常被复用”的情况。

内容的提问来源于stack exchange,提问作者Glorfindel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 12:55:20