Useful C# method for unit testing

Published 16 July 09 02:37 PM | Avi Pilosof 

I’m unit testing a UI that needs to show some lists in various sorted orders, and I wanted to ensure that my tests would cover that. I found this method to come in handy:

 

   1:  public static bool IsOrderedBy<T>(this IEnumerable<T> coll,
   2:                     Func<T, IComparable> val)
   3:  {
   4:      if (coll == null || coll.Count() == 0)
   5:          return true;
   6:   
   7:      var curVal = val(coll.ElementAt(0));
   8:      for (int i = 0; i < coll.Count(); i++)
   9:      {
  10:          if (val(coll.ElementAt(i)).CompareTo(curVal) < 0)
  11:              return false;
  12:   
  13:          curVal = val(coll.ElementAt(i));
  14:      }
  15:   
  16:      return true;
  17:  }

 

Here’s how to determine if a simple array is in order:

var arr = new int[] { 1, 2, 3, 5 };
bool ordered = arr.IsOrderedBy(i => i);

 

Here’s how you’d call it on a more complex object:

var arr = Enumerable.Range(1, 10)
    .Select(e => new
    {
        Name = "bob",
        Salary = 10 * e
    });
bool ordered = arr.IsOrderedBy(i => i.Salary);

 

 

Avi

Filed under:

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Petar Petrov said on July 16, 2009 10:46 AM:

The Count() extension method will iterate over the collection to find the count so you can cache it. The same is true for ElementAt. I think IsOrderedBy is not very good as extension method on IEnumerable<T> (in terms of performance). It's used for your unit test it's not production code but still you should be aware of this. Also no need to compare the first element against itself, and a sequence with only one element is sorted :)

When you consider this here's what I'm suggesting

public static bool IsOrderedBy<T>(this IEnumerable<T> sequence, Func<T, IComparable> extractor)

{

if (sequence == null)

{

return true;

}

var count = sequence.Count();

if (count <= 1)

{

return true;

}

var i = 0;

var currentValue = extractor(sequence.ElementAt(i++));

while (i < count)

{

var nextValue = extractor(sequence.ElementAt(i++));

if (currentValue.CompareTo(nextValue) > 0)

{

return false;

}

}

return true;

}

# guy said on July 16, 2009 4:41 PM:

This is not the most efficient implementation because of the coll.Count() which causes all the IEnumrable elements to be resolved, for better efficiency call MoveNext() explicitly.

# Avi Pilosof said on July 16, 2009 5:07 PM:

Good call on the perf issues, guys. I was only using this in unit tests for collections of 5-10 elements, so wasn't paying attention to them.

Leave a Comment

(required) 
(optional)
(required) 

  
Enter Code Here: Required

About Avi Pilosof

I'm a dev living in Sydney, working for Redmond - the best of both worlds :) My team writes applications (mostly web) used internally within MS.

Search

This Blog

Syndication

Page view tracker