Skip to content

Instantly share code, notes, and snippets.

@jasonrhodes
Last active August 29, 2015 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jasonrhodes/8829720 to your computer and use it in GitHub Desktop.
Save jasonrhodes/8829720 to your computer and use it in GitHub Desktop.
Testing dilemma

I'm writing tests for some small JavaScript libraries. In one small library I have a few "classes":

// lib/ChordMaker.js
var wheel = require("./wheel");

var Maker = function (options) {
    // ...
};

Maker.prototype.compute = function () {
    return wheel.modify(this.options.base, this.options.angle);
};

module.exports = Maker;

You can see the problem there when I am using the wheel dependency without injecting it. But "wheel" is an internal class that doesn't need to be exposed to the lib user--I don't want to force them to know what wheel is:

var maker = new ChordMaker(wheel); // wait wtf is wheel

So how do you inject internal dependencies without forcing the lib user to pass all of them in?

@jasonrhodes
Copy link
Author

One suggested solution:

// lib/ChordMakerWrapper.js
var wheel = require("./wheel"),
    Maker = require("./ChordMaker");

module.exports = function (options) {
    options.wheel = wheel;
    return new ChordMaker(options);
}

And then only use options.wheel inside the ChordMaker object. So then an end user would say:

var Maker = require("./lib/ChordMakerWrapper");

var maker = new Maker(options); // don't have to worry about wheel at all

Is that the best solution?

@jergason
Copy link

jergason commented Feb 5, 2014

I usually pass in dependencies to controllers but give them optional defaults. If you want to keep the options thing you could do something like this:

// lib/ChordMaker.js
var wheel = require("./wheel");

var Maker = function (options) {
    this.wheel = options.wheel || wheel
};

Maker.prototype.compute = function () {
    return this.wheel.modify(this.options.base, this.options.angle);
};

module.exports = Maker;

That way in prod you can get your real wheel implementation but in tests you can mock it out if you want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment