Using Dependency Injection to Write Better Tests

11 August 2016

Testing is given much emphasis in the Ember.js community, and testing tools have
showed steady progress to reduce the cost of writing tests of all types.

Lauren Tan wrote a great post
about how Dependency Injection (DI) can be used to decouple a parent component
from the internals of its child components. One of the gains of doing so is that
the parent component becomes more focused and thus easier to test.

In this post, I’m doing something similar, although much simpler. I want to show
you how to use DI in a simple helper function to make it easier to test.

Just your ordinary, run-of-the-mill function

Although the helper is an Ember (template) helper, the concepts could be very
easily transferred to other frameworks, libraries and even languages.

I recently had to modify a normalizeText helper function that looked
like this:

We’re, however, interested in the equality of the strings. If only there was a
way to replace that pesky Ember.String.htmlSafe call from the call site…

DI to the rescue

This is exactly what Dependency Injection can help us do. Instead of hard-coding
that “sanitizer” function dependency, the function could take it as a parameter
so that callers could inject it. Usually DI examples use (and thus inject) class
names or object instances but it is important to realize that the injected param
could be very “primitive”, like a simple function.

We’re now comparing simple strings which place nicely with assert.equal (with
===), and our test now passes.

Non-testing benefits

Code modifications introduced for the sake of testing usually also improve the
non-testing aspect. Here, we made it possible to pass any function before we
return the normalized text. We could, for example, use this to replace the <p>
tags with <span>s, if we so wish.