I am using NUnit in .net 4.5.2 project
Using the Collection assertions thusly:
Assert.That(first, Is.EquivalentTo(second));
This unit test passed
[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));
}
So then I used it on one of our classes that look equivalent in the debugger and it failed.
To test that, I created a simple reproduction, which still fails, now I'm really confused
[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));
}
The object definition, used in example two, I figure has to be something here:
public class SimpleObject
{
public string LastName { get; set; }
public string FirstName { get; set; }
public string Mi { get; set; }
public Int64 StudId { get; set; }
}
The second test fails with the message:
Expected: equivalent to < <_Test_DAL.SimpleObject> > But was: < <_Test_DAL.SimpleObject> >
at NUnit.Framework.Assert.That(Object actual, IResolveConstraint expression, String message, Object[] args) at _Test_DAL.TestADStudentDAL.Test_Int_ExampleDeepCompareCustomObjects2() in d:\TFS\JCDCHelper\2013\JCDCHelper.DAL_Tests\DAL\TestADStudentDAL.cs:line 152
But I totally expected it to pass
Why does the first pass, and the second fail? They look equivalent to me.
How do I create a test to deep compare those two objects, order-independent in .Net 4.5.2, as that is a standard object implementation for us
I want to write tests like the one above. We are moving from Sybase ASE to SqlServer, and I want to assert that the Ase call and the SqlServer call are returning the same data, and I can't just add order to every sql call.
P.S> For political reasons I can't update from .net 4.5.2 to .net 8.* at this time
FluentAssertions was by far the easiest answer.
It has a
list<T>.ShouldBeEquivalentTo(List <T>)
assertion, that performs a deep compare, ignoring order, and on failure returns an error with exactly the fields and values that did not match.
FluentAssertions v4.19.4 supports .Net 4.5.2
Package Manager Console: NuGet\Install-Package FluentAssertions -Version 4.19.4
Then wrote my Nunit test.
[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");
}