c# Nunit .Is.EquivalentTo 的行为与 List 的预期不符<T>

问题描述 投票:0回答:2

我在 .net 4.5.2 项目中使用 NUnit

这样使用集合断言:

Assert.That(first, Is.EquivalentTo(second));

本单元测试通过

        [Test] 
        public void Test_Int_ExampleDeepListCompare()
        {


            List<List<string>> first = new List<List<string>>()
            {
                new List<string> { "1", "3" },
                new List<string> { "1", "2" },
                new List<string> { "a", "b" }
            };

            List<List<string>> second = new List<List<string>>()
            {
                new List<string> { "1", "2" },
                new List<string> { "1", "3" },
                new List<string> { "a", "b" }
            };


            
            Assert.That(first, Is.EquivalentTo(second));
        }

然后我在我们的一个类中使用了它,在调试器中看起来相同,但它失败了。

为了测试,我创建了一个简单的复制品,但仍然失败,现在我真的很困惑

    [Test]
    public void Test_Int_ExampleDeepCompareCustomObjects2()
    {
        List<SimpleObject> rtnValFakeA = new List<SimpleObject>() { new SimpleObject() { FirstName = "Bob", LastName = "Jones", Mi = "a", StudId = 12345 } };
        List<SimpleObject> rtnValFakeb = new List<SimpleObject>() { new SimpleObject() { FirstName = "Bob", LastName = "Jones", Mi = "a", StudId = 12345 } };

        //assert with deep compare ignoring order - EWB
        Assert.That(rtnValFakeA, Is.EquivalentTo(rtnValFakeb));
    }

示例二中使用的对象定义,我认为这里必须是一些东西:

public class SimpleObject
{
    public string LastName { get; set; }

    public string FirstName { get; set; }

    public string Mi { get; set; }

    public Int64 StudId { get; set; }

}

第二次测试失败并显示消息:

预期:相当于< <_Test_DAL.SimpleObject> > 但是是:< <_Test_DAL.SimpleObject>>

at NUnit.Framework.Assert.That(Object actual, IResolveConstraint expression, String message, Object[] args) 在 _Test_DAL.TestADStudentDAL.Test_Int_ExampleDeepCompareCustomObjects2() 在 d:\TFS\JCDCHelper�3\JCDCHelper.DAL_Tests\DAL\TestADStudentDAL.cs:line 152

但我完全希望它通过

为什么第一次通过,第二次失败?他们看起来和我一样。

我如何创建一个测试来深入比较这两个对象,在 .Net 4.5.2 中与顺序无关,因为这是我们的标准对象实现

我想像上面那样编写测试。 我们正在从 Sybase ASE 迁移到 SqlServer,我想断言 Ase 调用和 SqlServer 调用返回相同的数据,我不能只为每个 sql 调用添加顺序。

P.S> 由于政治原因,我目前无法从 .net 4.5.2 更新到 .net 8.*

c# nunit .net-4.5
2个回答
1
投票

来自docs

CollectionEquivalentConstraint 测试两个 IEnumerables 是等价的——它们包含相同的项目,以任何顺序。

由于

SimpleObject
是引用类型,默认相等性由引用确定,您可以覆盖相等性成员,以便测试通过。例如:

public class SimpleObject : IEquatable<SimpleObject>
{
    // ...

    public bool Equals(SimpleObject other)
    {
        return LastName == other.LastName && FirstName == other.FirstName && Mi == other.Mi && StudId == other.StudId;
    }

    public override bool Equals(object? obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((SimpleObject)obj);
    }

    public override int GetHashCode()
    {
        return HashCode.Combine(LastName, FirstName, Mi, StudId);
    }
}

请注意,其他库如

FluentAssertions
支持 object graph comparison 没有这样的覆盖。


0
投票

FluentAssertions 是迄今为止最简单的答案。

它有一个

list<T>.ShouldBeEquivalentTo(List <T>) 

断言,执行深度比较,忽略顺序,失败时返回错误,其中包含不匹配的字段和值。

FluentAssertions v4.19.4 支持.Net 4.5.2

包管理器控制台: NuGet\Install-Package FluentAssertions -版本 4.19.4

然后写了我的Nunit测试。

        [Test]
        public void Test_Int_GetSimpleObject_CrossDbDeep()
        {
            List<SimpleObject> rtnValSyb = dal.GetSimpleObject(bForceSybase);
            List<SimpleObject> rtnValMs = dal.GetSimpleObject(bForceMsSql);

            Assert.AreNotEqual(rtnValSyb.Count, 0);
            Assert.AreNotEqual(rtnValMs.Count, 0);

            //assert with deep compare ignoring order - EWB
            rtnValSyb.ShouldBeEquivalentTo(rtnValMs,"If this fails, the data is probably out of synch");
        }
© www.soinside.com 2019 - 2024. All rights reserved.