Lessons Learned: Why Unit tests just won’t cut it
Over the last few days, I have had the wonderful experience of trying to implement a story just to find out, near the end, that nothing in it really worked. I had written unit tests and they all passed. My methods were hitting the dependencies and executing code exactly how I expected. And yet, my code wasn’t working. Worse was the fact that the code was throwing runtime exceptions preventing anything on the site from working.
The problem was that my code was trying to do a sort against data returned from a database call done via LING to SQL. And none of my unit tests exercised that call to the DB.
I was trying to generalized some sorts that I was doing through a builder class that returned a generic sort object. This sort object then performed that required sort on the Queryable. This meant that I had several methods like this:
public Sort<t> BuildSort(string sortBy) {
// some condition to figure out the proper sort
return new Sort<t>(properSortMethod());
}
private Expression<func <User, object>> SortByName() {
return user => user.Name;
}
private Expression<func <User, object>> SortByCreatedDate() {
return user => user.CreatedDate;
}
private Expression<func <User, object>> SortByIsActive() {
return user => user.IsActive;
}
The return value of each of these methods was then stored in a Sorts class which performs the sort.
private Expression<func <User, object>> sort;
public Sort(Expression<func <User, object>> sort) {
this.sort = sort;
}
public IQueryable<t> ApplySort(IQueryable<t> queryable) {
return queryable.OrderBy(sort);
}
To me, this all makes sense. And when applied to an in memory Queryable list, it works fine. When applied to a database, it croaks.
I learned two lessons out of this: first, always code in small chunks and check those small chunks into Subversion and second, when dealing with database code, always do integration tests early.
For reference, the problem was that LINQ cannot create a Query when the second part of the Expression is set object. It needs to explicitly typed as string, bool or DateTime?. However, using the pattern above, I don’t know how to properly store the sort in such a way that each builder method can return a specific sort and have those applied using a general method. if anyone has any ideas, please let me know.


