I'm having trouble comparing lists of objects that come back in an indeterminate order. I thought `ShouldBeEquivalentTo()` would take care of this for me, but it doesn't seem to :(
Check out the comments in following sample class for a more thorough description.
```
using System.Collections.Generic;
using FluentAssertions;
using NUnit.Framework;
namespace CrazyMo.Tests
{
[TestFixture]
public class ShouldBeEquivalentToTests
{
public class SomeClass
{
public int SomeInt { get; set; }
}
[Test]
public void DoSomethingAwesome_Scenario_ExpectedResult()
{
SomeClass some1 = new SomeClass { SomeInt = 1 };
SomeClass someOther1 = new SomeClass { SomeInt = 1 };
some1.ShouldBeEquivalentTo(someOther1); // This works
IEnumerable<int> someInts = new List<int> {1, 2};
IEnumerable<int> someOtherInts = new List<int> {2, 1};
someInts.Should().BeEquivalentTo(someOtherInts); // This works
someInts.Should().BeEquivalentTo(2, 1); // This works
IEnumerable<SomeClass> actual = new List<SomeClass>
{
new SomeClass{SomeInt = 1},
new SomeClass{SomeInt = 2}
};
// This does work
actual.ShouldBeEquivalentTo(new List<SomeClass>{
new SomeClass { SomeInt = 1 },
new SomeClass { SomeInt = 2 }
});
// The following is in reverse order, just like someOtherInts above.
// This doesn't work, but should?
actual.ShouldBeEquivalentTo(new List<SomeClass>
{
new SomeClass{SomeInt = 2},
new SomeClass{SomeInt = 1}
});
// This is similar to BeEquivalentTo(2, 1) above, but doesn't work.
// It's even in the correct order.
actual.Should().BeEquivalentTo(
new SomeClass { SomeInt = 1 },
new SomeClass { SomeInt = 2 }
);
}
}
}
```
Comments: I may not be understanding fully. You know the situation far better than I do. But here's my thinking... It's already able compare complex types (even ones that don't override `Equals()` or `==`) that aren't in a collection by using `ShouldBeEquivalentTo()`. So you can nested loop,comparing each member of the actual collection to each member of the expected collection, using the same magic as above. You can pretty easily prevent duplicates in either collection from triggering false positives... ```` var used = new List<int>(); foreach (var specimen in actual) { for (int i = 0; i < expected.Count; i++) { if (used.Contains(i)) { continue; } if (specimen == expected[i]) // Using the same magic comparison you use in ShouldBeEquivalentTo() { used.Add(i); break; } } } ```` Again, sorry if I've missed something obvious. You're the domain expert :)
Check out the comments in following sample class for a more thorough description.
```
using System.Collections.Generic;
using FluentAssertions;
using NUnit.Framework;
namespace CrazyMo.Tests
{
[TestFixture]
public class ShouldBeEquivalentToTests
{
public class SomeClass
{
public int SomeInt { get; set; }
}
[Test]
public void DoSomethingAwesome_Scenario_ExpectedResult()
{
SomeClass some1 = new SomeClass { SomeInt = 1 };
SomeClass someOther1 = new SomeClass { SomeInt = 1 };
some1.ShouldBeEquivalentTo(someOther1); // This works
IEnumerable<int> someInts = new List<int> {1, 2};
IEnumerable<int> someOtherInts = new List<int> {2, 1};
someInts.Should().BeEquivalentTo(someOtherInts); // This works
someInts.Should().BeEquivalentTo(2, 1); // This works
IEnumerable<SomeClass> actual = new List<SomeClass>
{
new SomeClass{SomeInt = 1},
new SomeClass{SomeInt = 2}
};
// This does work
actual.ShouldBeEquivalentTo(new List<SomeClass>{
new SomeClass { SomeInt = 1 },
new SomeClass { SomeInt = 2 }
});
// The following is in reverse order, just like someOtherInts above.
// This doesn't work, but should?
actual.ShouldBeEquivalentTo(new List<SomeClass>
{
new SomeClass{SomeInt = 2},
new SomeClass{SomeInt = 1}
});
// This is similar to BeEquivalentTo(2, 1) above, but doesn't work.
// It's even in the correct order.
actual.Should().BeEquivalentTo(
new SomeClass { SomeInt = 1 },
new SomeClass { SomeInt = 2 }
);
}
}
}
```
Comments: I may not be understanding fully. You know the situation far better than I do. But here's my thinking... It's already able compare complex types (even ones that don't override `Equals()` or `==`) that aren't in a collection by using `ShouldBeEquivalentTo()`. So you can nested loop,comparing each member of the actual collection to each member of the expected collection, using the same magic as above. You can pretty easily prevent duplicates in either collection from triggering false positives... ```` var used = new List<int>(); foreach (var specimen in actual) { for (int i = 0; i < expected.Count; i++) { if (used.Contains(i)) { continue; } if (specimen == expected[i]) // Using the same magic comparison you use in ShouldBeEquivalentTo() { used.Add(i); break; } } } ```` Again, sorry if I've missed something obvious. You're the domain expert :)