Is this the correct way to do Dependency Injection in Node?

1k Views Asked by At

I recently started a node project and as a Test-Driven Developer, I quickly ran into a dependency injection problem with my brand new module. Here's how I figured out I should do dependency injection. It's important to note I'm using vows as BDD framework and extend it with Sinon.

My module:

exports.myMethod = function () {
  var crypto = exports.cryptoLib || require('ezcrypto').Crypto;
  crypto.HMAC(
    crypto.SHA256,
    'I want to encrypt this',
    'with this very tasty salt'
  );
};

My test:

var vows = require('vows'),
  sinon = require('sinon');

vows.describe('myObject').addBatch({
  'myMethod':{
    'topic':true,
    'calls ezcrypto.HMAC':function () {
      var myObject = require('../playground.js');
      var mock = sinon.mock(require('ezcrypto').Crypto);

      myObject.cryptoLib = mock;
      myObject.cryptoLib.HMAC = mock.expects("HMAC").once().withExactArgs(
        require('ezcrypto').Crypto.SHA256,
        'I want to encrypt this',
        'with this very tasty salt'
      );
      myObject.cryptoLib.SHA256 = require('ezcrypto').Crypto.SHA256;
      myObject.cryptoLib = mock;
      myObject.myMethod();
      mock.verify();
    }
  }
}).export(module);

Do you think this the correct way to go? I like this solution because it doesn't require more when you use the module (like adding "()" after the require statement).

1

There are 1 best solutions below

6
On

It's not good way to trash your code with test stuff. Line 2 of your code

var crypto = exports.cryptoLib || require('ezcrypto').Crypto;

Looks like unnecesary interface. I suggest you to replace it with

var crypto = require('ezcrypto').Crypto;

Much cleaner. And in test just mock Crypto method of 'ezcrypto' module. Just do not forget to revert it back after using.