我在 .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.*
来自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 没有这样的覆盖。
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");
}