Monday, July 28, 2014

Joe Rainsberger - Integration Tests Are a Scam

Just wanted to pass on this interesting video I came across on the web.  The video is titled Integration Tests Are a Scam by Joe Rainsberger in 2009.  Joe suggests using smaller more targeted tests as a first line of defense to guard against regression caused by refactoring.

INFOQ - Integration Tests Are a Scam

Saturday, July 26, 2014

IOC - Newables & Injectables and the Abstract Factory

In my reading around the blogs and StackOverflow posts this week I came across the topic of newables and injectables in Ioc.  If your not familiar with the topic the following two posts explain in detail the issue of these two types of objects in our code.

To new or not to new
How to write testable code

To summarize, newables should only ask for other newables, and injectables should only ask for other injectables in their constructors.  Newables can be aware of injectables (pass them through methods), but should not take instances of injectables in the constructor.  If these rules are followed, life will be good, your system will be loosely coupled and you'll be in a state of testing nirvana.

The reality is that very often you'll have a condition in the code that is unknown until run time. Say you have a class that coordinates some sort of work, and you end up with something like this.
public class WorkDoer : IWorkDoer
   public WorkDoer(taskRunner ITaskRunner, workToBeDone WorkObject){}

In the above example, the rule of injectables and newables has been broken, and yes it does complicate things, but not horribly.  Now to deal with this in your code, an Abstract Factory will be needed to create a WorkDoer instance.  The Abstract Factory is great because it allows us to keep our code testable and loosely coupled.  In the test harness, if your using a mocking framework you can simply have your abstract factory return a mock of whatever the factory creates.
Following the newable and injectable rule certainly makes life easier.  It keeps each part of the code relatively simple to test in isolation from other parts of code.  However, in the case where an injectable must have an instance of a newable passed through the constructor, the Abstract Factory pattern will save the day. 

Mark Seemann, author of Dependency Injection in .Net, has this post on SO which is an answer to a the issue discussed above.  I point this out as Mark's SO answers have helped clarify many of my questions around IOC.

Monday, July 21, 2014

Linq Distinct - Override Equals and GetHashCode

Recently in our code base I ran across a portion of code that was selecting out a distinct set of objects. The Equals method had been overridden to provide equality based on values of the object, and was being used to compare object equality between objects in a list. If the objects proved to be equal, the first instance was transferred into a new list. There was a comment beside this code that said something like "Check into using LINQ Distinct for this"...

After setting up a unit test and overriding the equals method, I noted that I could not get my tests to pass.  I turned to the MSDN docs for help. The issue was the GetHashCode method must also be overridden. The idea behind this is that when doing an equality comparison GetHashCode, and Equals are both used by GenericEqualityComparer<T>.   GetHasCode is used to help determine if an object is possibly equal, if it is then the Equals method will be called to determine absolute equality. If your object is mutable, getting a hash code from it can be impractical.  In this case returning 1 as the hash code is probably the best thing though it will affect look-up performance.

Once this was understood then there comes the more nuanced issue of choosing to implement IEquatable<T>. If you don't implement this interface, methods in the BCL that use the GenericEqualityComparer<T> will still function, so what's the point? Once again the MSDN docs explain how things work.

"For a value type, you should always implement IEquatable(Of T) and override Object.Equals(Object) for better performance. Object.Equals boxes value types and relies on reflection to compare two values for equality. Both your implementation of Equals and your override of Object.Equals should return consistent results.
If you implement IEquatable(Of T), you should also implement IComparable(Of T) if instances of your type can be ordered or sorted. If your type implements IComparable(Of T), you should also always implement IEquatable(Of T)."

A few more things to think about...  Don't forget to override the equality and inequality operators to keep object behavior consistent.  If your overriding Equals, you may want to think about sealing your class, to keep inherited classes from messing up on an Equals implementation.