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

对比集合时如何在错误信息中展示标识字段(主键)

单元测试优化:自定义对象集合对比的错误信息显示

在单元测试中对比包含标识属性(主键)的复杂对象集合时,当前错误信息仅显示集合索引(如actual[1].Prop2),无法直接定位到具体是哪个对象(通过主键MyKey)出了问题。示例错误信息如下:

Expected property actual[1].Prop2 to be the same string, but they differ at index 0:
↓ (actual)
"invalidValue"
"expectedValue"
↑ (expected).

希望能在错误信息中展示类似MyKey = "value1"的标识属性内容,方便快速定位问题。相关代码如下:

class Foo
{
    public string MyKey { get; set; }
    public string Prop2 { get; set; }
}

[Fact]
public void Test()
{
    var expected = new[] {
        new Foo { MyKey = "value0", Prop2 = "expectedValue" },
        new Foo { MyKey = "value1", Prop2 = "expectedValue" },
    };
    var actual = new[] {
        new Foo { MyKey = "value0", Prop2 = "expectedValue" },
        new Foo { MyKey = "value1", Prop2 = "invalidValue" },           
    };

    actual.Should().BeEquivalentTo(expected, options => {
        // 原代码中Prop1不存在,属于笔误
        // ctx.Subject.Prop1.Should().Be(ctx.Expectation.Prop1);
        return options;
    });
}

优化方案(基于FluentAssertions)

要让错误信息显示对象的标识属性,需从对象匹配逻辑和错误信息格式化两方面配置:

  1. 按主键匹配对象(可选)
    如果集合不需要严格按顺序对比,可指定用MyKey作为匹配依据,避免因顺序不同导致的错误匹配:
options.ByMember(m => m.MyKey);

如果需要保持顺序对比,使用:

options.WithStrictOrdering();
  1. 自定义错误信息中的对象标识
    通过配置等价性步骤,自定义Foo对象的显示名称,让错误信息直接展示MyKey的值:
options.ConfigureEquivalencyStepForType<Foo>(step =>
    step.FormatSubject(ctx => $"Foo(MyKey = \"{ctx.Subject.MyKey}\")"));

也可针对单个属性对比时自定义错误消息,明确关联对应的MyKey:

options.Using<string>(ctx =>
{
    ctx.Subject.Should().Be(ctx.Expectation, 
        $"Foo的MyKey为\"{ctx.ParentContext.Subject.MyKey}\"时,{ctx.Path}属性不匹配");
}).WhenTypeIs<string>();

修改后的完整测试代码

class Foo
{
    public string MyKey { get; set; }
    public string Prop2 { get; set; }
}

[Fact]
public void Test()
{
    var expected = new[] {
        new Foo { MyKey = "value0", Prop2 = "expectedValue" },
        new Foo { MyKey = "value1", Prop2 = "expectedValue" },
    };
    var actual = new[] {
        new Foo { MyKey = "value0", Prop2 = "expectedValue" },
        new Foo { MyKey = "value1", Prop2 = "invalidValue" },           
    };

    actual.Should().BeEquivalentTo(expected, options =>
    {
        // 按MyKey匹配对象(若不需要顺序可启用)
        // options.ByMember(m => m.MyKey);
        // 保持顺序对比
        options.WithStrictOrdering();
        // 自定义Foo对象的显示格式
        options.ConfigureEquivalencyStepForType<Foo>(step =>
            step.FormatSubject(ctx => $"Foo(MyKey = \"{ctx.Subject.MyKey}\")"));
        return options;
    });
}

优化后的错误信息示例

Expected property Foo(MyKey = "value1").Prop2 to be the same string, but they differ at index 0:
↓ (actual)
"invalidValue"
"expectedValue"
↑ (expected).

这样就能直接通过错误信息定位到具体是MyKey=value1的对象出了问题,无需再通过索引反推。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 13:14:56