---
title: Simplify your Unit Tests with Dependency Injection for JavaScript Modules
description: Use Dependency Injection to simplify your unit tests with the JavaScript module format you're already using and without changing your code.
image: https://www.bitovi.com/hubfs/injection.jpg
---

- ![AI implementation](https://www.bitovi.com/hubfs/AIConsultingIcon.svg)
  
  [AI implementation](https://www.bitovi.com/services/ai-consulting)
- ![Systems engineering](https://www.bitovi.com/hubfs/icon%20-%20backend.svg)
  
  [Systems engineering](https://www.bitovi.com/services/systems-engineering-consulting)
- ![Project Management](https://www.bitovi.com/hubfs/icon%20-%20PM.svg)
  
  [Project Management](https://www.bitovi.com/services/agile-project-management-consulting)
- ![Product Design](https://www.bitovi.com/hubfs/icon%20-%20design.svg)
  
  [Product Design](https://www.bitovi.com/services/product-design-consulting)
- ![Frontend development](https://www.bitovi.com/hubfs/icon%20-%20frontend.svg)
  
  [Frontend development](https://www.bitovi.com/services/frontend-development-consulting)
- [View more
  
  →
  
  ](https://www.bitovi.com/digital-consulting-services)

We're Experts in...

- [JavaScript](https://www.bitovi.com/services/frontend/javascript-consulting)
- [AI training](https://www.bitovi.com/ai-training-for-software-engineers)
- [Angular](https://www.bitovi.com/services/frontend/angular-consulting)
- [Design systems](https://www.bitovi.com/services/axure-figma-migration)
- [React](https://www.bitovi.com/services/frontend/react-consulting)
- [Temporal](https://www.bitovi.com/services/backend/temporal-consulting)
- [React Native](https://www.bitovi.com/services/frontend/react-consulting/react-native)
- [Node.js](https://www.bitovi.com/services/backend/nodejs-consulting)

Showcase

![Yum! Brands](https://www.bitovi.com/hubfs/yum-showcase-link-1.png)

[View case study](https://www.bitovi.com/en/bitovi-yum-case-study)

More Projects

- [![Levi's](https://www.bitovi.com/hubfs/levis.svg)](https://www.bitovi.com/web-application-consulting-work/levis-ecommerce-responsive-redesign)
- [![Christie's International Real Estate](https://www.bitovi.com/hubfs/christies.svg)](https://design.bitovi.com/christies)
- [![BAFS](https://www.bitovi.com/hubfs/bafs.svg)](https://www.bitovi.com/ux-design-consulting/ux-case-studies/bafs-ppp)
- [View more
  
  →
  
  ](https://www.bitovi.com/our-software-consulting-work)

Open Source Tools

We build powerful tools and open source them to support the community.

[See what we've built →](https://www.bitovi.com/open-source)

- [![Blog](https://www.bitovi.com/hubfs/icon%20-%20blog.svg)
  
  BlogWe post about delivering products and solving problems.
  
  ](https://www.bitovi.com/blog)
- [![Partnerships](https://www.bitovi.com/hubfs/Handshake-1.svg)
  
  PartnershipsLearn about Bitovi's technology partners
  
  ](https://www.bitovi.com/partnerships)
- [![Academy](https://www.bitovi.com/hubfs/icon%20-%20academy%20(4).svg)
  
  AcademyFree courses to build delivery skills
  
  ](https://www.bitovi.com/academy)
- [![Open source tools](https://www.bitovi.com/hubfs/icon%20-%20open%20source.svg)
  
  Open source toolsUse or contribute to our community
  
  ](https://www.bitovi.com/open-source)

Let's Connect

- [![Discord](https://www.bitovi.com/hubfs/DiscordLogo.svg)
  
  Discord
  
  ](https://discord.gg/J7ejFsZnJ4)
- [![LinkedIn](https://www.bitovi.com/hubfs/LinkedinLogo.svg)
  
  LinkedIn
  
  ](https://www.linkedin.com/company/bitovi/)
- [![GitHub](https://www.bitovi.com/hubfs/GithubLogo.svg)
  
  GitHub
  
  ](https://github.com/bitovi/)

![Eggbot](https://www.bitovi.com/hubfs/build_assets/bitovi-limbo-cms-react/338/js_client_assets/assets/eggbot-LTGhdSGL.png)

Name *

Work Email *

Phone

What's your project?

Send

### Contact Us

(312) 620-0386contact@bitovi.com

 March 9, 2016

# Simplify your Unit Tests with Dependency Injection for JavaScript Modules

 Use Dependency Injection to simplify your unit tests with the JavaScript module format you're already using and without changing your code.

![Kevin Phillips](https://app.hubspot.com/settings/avatar/d2b9499fdabb775938188c33d09da7e8)

 Kevin Phillips

 Director of Backend Development

Share:

[![Twitter](https://www.bitovi.com/hubfs/limbo-generated/_astro/twitter-white.os3xLc3C_Z2nW4or.svg) ](https://twitter.com/intent/tweet?text=) [![Reddit](https://www.bitovi.com/hubfs/limbo-generated/imgs/icons/reddit.png) ](http://reddit.com/submit?url=)

> Note: Come join us for a live training on [Dependency Injection with StealJS on Wednesday, March 16, 2016 at 12:30 PM CST](https://www.youtube.com/watch?v=RG3UOB2sI3Q).

Writing small modules with good unit tests greatly increases the maintainability of your code. However, it can be difficult to test a module without first understanding how its dependencies work. Dependency Injection (DI) allows you to isolate your tests to exactly what you’re trying to test.

![dependency-injection-gif-animation.gif](https://www.bitovi.com/hubfs/Imported_Blog_Media/dependency-injection-gif-animation.gif)

While many Dependency Injection implementations require you to use them as plumbing throughout your code, you can use Dependency Injection with the JavaScript module format you’re already using by loading your modules with StealJS. No need to modify your code -- use Dependency Injection when you want it and your existing module format to load modules everywhere else.

## What is Dependency Injection?

Dependency injection is a Computer Science design principle that has been around a long time. There are lots of articles ([here](http://martinfowler.com/articles/injection.html) [are](http://www.theserverside.com/news/1321158/A-beginners-guide-to-Dependency-Injection) a [few](http://www.jamesshore.com/Blog/Dependency-Injection-Demystified.html)) that go in depth on this topic, but I’ll use this simple definition:

> **Dependency Injection** - replacing the code that will be loaded when a JavaScript module is imported.

The most useful way to use DI in JavaScript is to simplify unit testing. To better understand this, we'll go over the simple example shown in the GIF above.

Take these two modules:

- `user` - exports a `name` function that makes a call to the server and returns the current user’s name.
- `navigation` - exports a `greeting` function that uses the `user.name` function to display “Welcome Back, *name*!” if we know the user’s name or just “Welcome!” if we don’t.

In the next sections, we'll show how to unit test them, with and without using DI.

### Testing Without Dependency Injection

If you want to test `navigation.greeting` without Dependency Injection, you need `user.name` to return a value. One way to do this is to intercept the request being made to the server and return a mocked AJAX response with the data needed for your test case.

With this approach, you’re testing more than just the `greeting` function:

![what-youre-testing-injection](https://www.bitovi.com/hubfs/Imported_Blog_Media/what-youre-testing-injection.png)

In order to set this up you also have to know implementation details about the `user` module.

- What request is it making to the server?
- Is it using a library or framework to make the request?
- What does the server’s response look like?

If the `user` module changes, you might have to modify your test, even if the changes don’t affect the `navigation` module. Consider the following scenarios:

What happens if the server’s response changes?

![server-response-changes](https://www.bitovi.com/hubfs/Imported_Blog_Media/server-response-changes.png)

What happens if the `user` module starts caching its data in localStorage?

![cache-to-localstorage](https://www.bitovi.com/hs-fs/hubfs/Imported_Blog_Media/cache-to-localstorage.png?width=613&height=489&name=cache-to-localstorage.png)

The paradigm of unit testing is broken. Unit testing should be isolating and testing a single module, but in practice, this unit test is dependent on many modules that we’re not trying to test.

The tight coupling of the `navigation` module’s tests to the implementation of the `user` module leads to brittle tests and lots of frustration - if you don’t just give up on testing the module altogether.

### Testing With Dependency Injection

Testing the `navigation` module becomes much easier when using dependency injection because you can inject a version of the `user` module that does exactly what you need for your `navigation` module’s tests:

![Testing-With-Dependency-Injection](https://www.bitovi.com/hubfs/Imported_Blog_Media/Testing-With-Dependency-Injection.png)

Now if the implementation of `user.name` changes, it won’t affect your tests at all.

## Dependency Injection with StealJS

[StealJS](https://stealjs.com) is a client-side JavaScript module loader. A recent extension to steal, [steal-clone](https://stealjs.com/docs/steal.steal-clone.html), added the ability to do dependency injection of JavaScript modules. Here is the `navigation` example using steal-clone:

Navigation Module Code:

```
import { name } from 'models/user';

export class Navigation {
  greeting() {
    return name()
      .then(name => {
        return name ?
          `Welcome Back, ${name}!` :
          'Welcome!';
      });
  }
};
```

Navigation Test Code:

```
import QUnit from 'qunit';
import clone from 'steal-clone';

let navigation, name;

QUnit.module('navigation', {
  beforeEach(assert) {
    const done = assert.async();

    clone({
      'models/user': {
        name() {
          return Promise.resolve(name);
        }
      }
    })
    .import('navigation')
    .then(({ Navigation }) => {
      navigation = new Navigation();
      done();
    });
  }
});

QUnit.test('greeting - no name', (assert) => {
  const done = assert.async();

  name = null;

  navigation
  .greeting()
  .then(greeting => {
    QUnit.equal(greeting, 'Welcome!');
    done();
  });
});

QUnit.test('greeting - with name', (assert) => {
  const done = assert.async();

  name = 'Kevin';

  navigation
  .greeting()
  .then(greeting => {
    QUnit.equal(greeting, 'Welcome Back, Kevin!');
    done();
  });
});
```

You’ll notice a few things in this code:

- This example is using ES6 module syntax, but if you prefer CommonJS or AMD that is fine too; steal-clone will work with whatever syntax you choose.
- You only use Dependency Injection exactly where you want it. You’re not forced to use any libraries or frameworks in your modules.

This simple example shows how Dependency Injection can isolate your tests to exactly the module you’re testing and how simple it is to use DI with StealJS and steal-clone. If you want to start simplifying your tests and you’re already using StealJS, take a look at the [docs](https://stealjs.com/docs/steal.steal-clone.html) for steal-clone and start using it today. If you’re not using StealJS, take a look at its [homepage](https://stealjs.com) and [docs](https://stealjs.com/docs/steal.html) to get started.

[![Tag for development](https://www.bitovi.com/hubfs/limbo/icons/tag.svg) development ](https://www.bitovi.com/blog/topic/development)

 Previous Post

![](https://www.bitovi.com/hs-fs/hubfs/donejs-banner.jpg?height=117&name=donejs-banner.jpg) [ Lessons from a Decade of JavaScript Consulting: Bitovi’s 10 Core Principles ](https://www.bitovi.com/blog/javascript-consulting-core-principles)

  

 Next Post

![donjs-banner.jpg](https://www.bitovi.com/hs-fs/hubfs/donjs-banner.jpg?height=117&name=donjs-banner.jpg) [ Creating a generator for DoneJS applications ](https://www.bitovi.com/blog/creating-a-generator-for-donejs-applications)

```json
{
  "@context" : "http://schema.org",
  "@type" : "Organization",
  "address" : {
    "@type" : "PostalAddress",
    "addressCountry" : "United States",
    "addressLocality" : "Libertyville",
    "addressRegion" : "IL",
    "postalCode" : "60048",
    "streetAddress" : "1134 Pine Tree Lane "
  },
  "alternateName" : "Bitovi",
  "areaServed" : {
    "@type" : "GeoCircle",
    "geoMidpoint" : {
      "@type" : "GeoCoordinates",
      "latitude" : "41.8781",
      "longitude" : "87.6298"
    },
    "geoRadius" : "5000 km"
  },
  "description" : "Bitovi is a UX, UI design and front-end JavaScript development consulting company",
  "email" : "contact@bitovi.com",
  "image" : "https://www.bitovi.com/hubfs/bitovi-logo-x2.png",
  "logo" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg",
  "mainEntityOfPage" : {
    "@id" : "https://www.bitovi.com/blog/dependency-injection-for-javascript-modules",
    "@type" : "WebPage",
    "description" : "Use Dependency Injection to simplify your unit tests with the JavaScript module format you're already using and without changing your code."
  },
  "naics" : "541511",
  "name" : "Bitovi Web App Consulting",
  "sameAs" : [ "https://www.facebook.com/BitoviLLC/", "https://twitter.com/bitovi", "https://www.linkedin.com/company/bitovi" ],
  "telephone" : "312-620-0386",
  "url" : "http://bitovi.com"
}
```

```json
{
  "@context" : "http://schema.org",
  "@type" : "BlogPosting",
  "author" : {
    "@type" : "Person",
    "name" : "Kevin Phillips"
  },
  "dateModified" : "December 5, 2018, 2:41:44 AM",
  "datePublished" : "2016-03-09 17:24:23",
  "description" : "Use Dependency Injection to simplify your unit tests with the JavaScript module format you're already using and without changing your code.",
  "headline" : "Simplify your Unit Tests with Dependency Injection for JavaScript Modules",
  "image" : {
    "@type" : "ImageObject",
    "url" : "http://cdn2.hubspot.net/hubfs/2171535/injection.jpg"
  },
  "publisher" : {
    "@type" : "Organization",
    "logo" : {
      "@type" : "ImageObject",
      "url" : "https://www.bitovi.com/hubfs/bitovi-logo-23-1.svg"
    },
    "name" : "Bitovi"
  }
}
```