Reputation: 2974
a quick projection question. I have a collection of objects (unchangeditems) in a test method, and would like to ensure they match my 'expected' elements. As shown you could do it by element, but this isn't ideal. I'm sure its possible to use projection to get down to the string variable (LMAA_CODE - don't ask about the capitals!) along the lines of the bottom line below. I'd appreciate a hand.
Thanks!
// Works but not very elegant
Assert.AreEqual(result.unchangedItems[0].LMAA_CODE,expectedunchangedItems[0]);
Assert.AreEqual(result.unchangedItems[1].LMAA_CODE,expectedunchangedItems[1]);
Assert.AreEqual(result.unchangedItems[2].LMAA_CODE,expectedunchangedItems[2]);
Assert.AreEqual(result.unchangedItems[3].LMAA_CODE,expectedunchangedItems[3]);
// ?Can something like this be done? eg result.unchangedItems => result.unchangedItems.LMAA_CODE
Assert.IsTrue(Enumerable.SequenceEqual(result.unchangedItems.LMAA_CODE, expectedunchangedItems));
Upvotes: 2
Views: 307
Reputation: 17196
You could also use a "Zip" extension method.
Assert.AreEqual(result.unchangedItems.Count, expectedunchangedItems.Count);
result.unchangedItems.Zip(expectedunchangedItems, (a, b) => Tuple.Create(a, b))
.ForEach(p => Assert.AreEqual(p.Item1.LMAA_CODE, p.Item2));
This way, the exception reports which value was not expected. The Zip() method is included in .NET 4, but I personally prefer to use my own, and of course you'd want a ForEach() too:
// I actually have a Pair<A,B> struct that I prefer to use, but
// KeyValuePair or Tuple works almost as well.
public static IEnumerable<Tuple<A, B>> ZipTuples<A, B>(this IEnumerable<A> a, IEnumerable<B> b)
{
IEnumerator<A> ea = a.GetEnumerator();
IEnumerator<B> eb = b.GetEnumerator();
while (ea.MoveNext() && eb.MoveNext())
yield return new Tuple<A, B>(ea.Current, eb.Current);
}
public static void ForEach<T>(this IEnumerable<T> list, Action<T> action)
{
foreach (T item in list)
action(item);
}
Usage:
Assert.AreEqual(result.unchangedItems.Count, expectedunchangedItems.Count);
result.unchangedItems.ZipTuples(expectedunchangedItems)
.ForEach(p => Assert.AreEqual(p.Item1.LMAA_CODE, p.Item2));
Upvotes: 0
Reputation: 29863
What about:
for (int i = 0; i < result.unchangedItems.Count; i++) {
Assert.AreEqual(result.unchangedItems[i].LMAA_CODE, expectedUnchangedItems[i]);
}
You can also do:
Assert.IsFalse(result.unchangedItems.Where((r,i) => expectedUnchangedItems[i] != r.LMAA_CODE).Any())
.Any()
will return true if the filtered sequence contains elements, and it shouldn't. That's why you call IsFalse
. If your testing framework (or whatever you are using) does not have that, you can always do Assert.AreEqual(____, false)
.
Upvotes: 1
Reputation: 160952
You were almost there already, just added a projection to LMAA_CODE:
Assert.IsTrue(Enumerable.SequenceEqual(result.unchangedItems.Select( x=> x.LMAA_CODE),
expectedunchangedItems));
Upvotes: 4
Reputation: 34250
You can use LINQ and Zip
:
Assert.IsTrue(result.unchangedItems.Zip(expectedunchangedItems, (actual, expected) => actual.LMAA_CODE == expected).All(value => value));
Upvotes: 1