Javascript is the most testable mainstream language.. Say what!?

As mentioned in a earlier blog post, observability is a crucial aspect of being able to test the outcome of a method call. Control of the system or objects under test is just as important. Control in this case means power over new(). Lets look at the most simple example:

class TestMe
{
	internal TestMe()
}

No control over the instantiation of the class, which means we cannot create an isolated test of the class in a separate assembly. Other flavours of this lack of power over instantiation includes private constructors, private or internal factory methods etc.

Moving on to a different aspect of controllability:

class Foo
{
  private IBar bar = new Bar()
  
  public void DoSomethingWithBar()
  {
    bar.DoSomething()
  }
}

Here the interaction with bar is unobservable since we are not able to replace bar with our own test double or mock. Another consequence is that Foo cannot be tested in isolation. The problem being that new is not late-bound, it binds to a specific concrete class! In this case Bar. The use of new forces us to use a specific class and leaves us with no way of pointing the code to our own test class. Imagine removing the capability of late-bound methods, as realised by different implementations of the same interfaces or virtual methods that are overridden in subclasses. This would remove a lot of the power of OO. The new operator is seriously flawed in this respect.

Dependency injection can be seen as one way of mitigating the problems with new by simple removing its usage! It moves the choice of which class to instantiate to runtime, in other words, the class is late-bound.

The problem completely goes away in a dynamically typed language where monkey patching is available such as Javascript:

function testFoo()
{
  var foo = new Foo()
  foo.bar = createMockOfBar()
  ...  continue test and assert interaction with bar ..
}

This means any part of an object graph can be replaced ad nauseaum, resulting in complete control and countless options for observing the result and interactions of methods under test, which leaves room for any experiment or test imaginable.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s