Recently I have been involved in a discussion about let’s just say modern JavaScript techniques. In the discussion a point was made about how difficult it is to perform dependency injection, which I completely disagree. Not only is JavaScript dependency injection (DI) relatively easy, JavaScript’s dynamic nature makes it extremely easy to stub and mock objects and their members.

To me the harder part is writing or finding a library that is a testable mock, this is one of the strengths Angular has over other libraries, shipping with testible mock objects, at least that is what I have read. My favorite to actually test dependencies is with sinonjs, a mocking and stubbing library. Sinon does not do anything with dependency injection, instead it leverages JavaScript’s dynamic nature and replaces dependencies with mocks, stubs and spies.

I tend to design my libraries with natural DI capabilities, which can be very handy if you do want to replace an entire object dependency. It is actually a product of designing my libraries to depend on an implied interface (remember JavaScript has no real interface concept) so I can swap out libraries later.

There are effectively 2 places I can inject a mock library when I design a module. Let me show with my SPA library’s code. First is the self-executing anonymous function (SEAF). This is something I actually picked up from jQuery:

(function (window, $, undefined) {

//actual module definition here

})(window, $);

Here there are 3 parameters defined and a pair of arguments passed. I do window more for minification purposes. The $ is where I would ‘inject’ jQuery or a library that supports the jQuery interface. I actually wrote a small utility library called dollarbill library that is compatible with the jQuery interface for methods I actually use. There are several other jQuery like micro libraries available, so just assume you might want to use one of them instead of the full jQuery dependency. Because the SEAF lets you pass in an object for the $ you are decoupled from actually using jQuery and should be able to use a similar library. The last argument is a defensive mechanism to guard against someone mucking with the definition of undefined.

Let me make a little side statement about implementing an interface. I am not one that believes you need a 100% coverage when implementing an interface for a library like jQuery. There are actually several modules that comprise jQuery, several I do not use any longer, like animations. I rely on CSS to perform animations today, not JavaScript. So my implementation of the jQuery interface would completely omit those members. If you actually look at many C## and Java classes they often implement multiple interfaces. The same concept applies here. When I say I am implementing a jQuery interface I am implementing members in my library that I actually use.

#javascript #dependency #injection

Two Simple Javascript Dependency Injection Techniques
1.35 GEEK