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

使用NUnit断言Type集合时,Has.All.Property(nameof(Type.Namespace))为何失败?

NUnit集合断言中Type.Namespace属性找不到的问题解决

我想用NUnit断言所有目标Type都属于预期命名空间,写了下面的代码:

IReadOnlyCollection<Type> types = GetInterestingTypes(); // 其他地方定义的方法
Assert.That(types, Has.All.Property(nameof(Type.Namespace)).StartsWith("MyNamespace"));

这段代码抛出ArgumentException:Property Namespace not found on ...,但单独对每个Type执行断言Has.Property(nameof(Type.Namespace)).StartsWith("MyNamespace")却能正常通过。

最小复现代码

using System;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;

using NUnit.Framework;

namespace MyNamespace
{
    internal class MyTests
    {
        [Test]
        public void TestsWithinNamespace()
        {
            var types = new[] {typeof(Foo), typeof(NestedNamespace.Bar)};

            foreach (var type in types)
            {
                // 执行通过
                Assert.That(type, Has.Property(nameof(Type.Namespace)).StartsWith("MyNamespace"));
            }

            // 执行失败
            Assert.That(types, Has.All.Property(nameof(Type.Namespace)).StartsWith("MyNamespace"));
        }
    }

    public class Foo { }

    namespace NestedNamespace
    {
        public class Bar { }
    }
}

错误信息

System.ArgumentException : Property Namespace was not found on MyNamespace.Foo.
Parameter name: name
   at NUnit.Framework.Constraints.PropertyConstraint.ApplyTo[TActual](TActual actual)
   at NUnit.Framework.Constraints.AllItemsConstraint.ApplyTo[TActual](TActual actual)
   at NUnit.Framework.Assert.That[TActual](TActual actual, IResolveConstraint expression, String message, Object[] args)
   at MyNamespace.MyTests.TestsWithinNamespace()

问题原因

NUnit的Has.All.Property约束处理Type对象时,会尝试通过实例属性查找Namespace,但Type.Namespace本质是依赖反射的属性(属于TypeInfo范畴),集合断言的属性查找逻辑和单个对象断言的逻辑存在差异,导致无法识别该属性。

解决方法

有两种可靠的修复方式:

方式1:使用Has.All.Matches自定义匹配逻辑

手动在匹配器中获取Namespace属性,绕开NUnit的属性查找逻辑:

Assert.That(types, Has.All.Matches<Type>(t => t.Namespace.StartsWith("MyNamespace")));

方式2:投影后断言

先将集合中的Type转换为对应的命名空间字符串,再断言所有字符串符合要求:

Assert.That(types.Select(t => t.Namespace), Has.All.StartsWith("MyNamespace"));

这两种方式都能正确验证所有Type的命名空间是否符合预期,规避了NUnit集合属性断言的逻辑问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 22:25:17