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

XUnit+Shouldly单元测试ShouldContainKeyAndValue校验字典值一致仍失败问题

问题根因

Shouldly的ShouldContainKeyAndValue方法对引用类型默认使用引用相等性做比对:你在校验时传入的new []{ "'Id' must be equal to '0'." }是新创建的数组实例,而业务逻辑返回的字典里存储的是另一个数组实例,哪怕两个数组的元素完全一致,只要引用地址不同,就会判定为值不相等。你单独校验键Id可以通过,是因为字符串是不可变类型,相等判断默认走值比对,没有引用问题。

解决方案

方案1:拆分校验(最常用,可读性最高)

先校验键存在,再单独对值做数组内容比对,Shouldly的ShouldBe对集合类型默认按元素内容比对:

// Assert
result.IsSuccess.ShouldBeFalse();
result.ResultType.ShouldBe(ResultType.Invalid);
var errorDict = (Dictionary<string, string[]>)result.Data;
// 先校验键存在
errorDict.ShouldContainKey("Id");
// 再校验数组内容一致
errorDict["Id"].ShouldBe(new []{ "'Id' must be equal to '0'." });

方案2:链式校验

直接对取出的键值做内容断言:

((Dictionary<string, string[]>)result.Data)
    .ShouldContainKey("Id")
    .ShouldSatisfy(errors => errors.SequenceEqual(new []{ "'Id' must be equal to '0'." }));

方案3:传入自定义比较器(适合批量校验场景)

如果需要多处校验字典的数组值,可以自定义IEqualityComparer<string[]>传入ShouldContainKeyAndValue,让方法按内容比对数组:

public class StringArrayComparer : IEqualityComparer<string[]>
{
    public bool Equals(string[] x, string[] y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(string[] obj)
    {
        return obj.Aggregate(0, (hash, s) => hash ^ s.GetHashCode());
    }
}

// 校验时使用
((Dictionary<string, string[]>)result.Data)
    .ShouldContainKeyAndValue("Id", new []{ "'Id' must be equal to '0'." }, new StringArrayComparer());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 05:54:03