thlorenz/proxyquire

How to stub out other module dependencies

Closed this issue · 1 comments

I wish to to stub out a dependency in a sub module I am requiring in, my file structure is as follows:

index.js

let MyModule = require('./src/index.js');
MyModule = new MyModule();
module.exports = MyModule;

./src/index.js

const Cache = require('cache');

const MyModule = function MyModule() {

  const self = this;
  self.cache = new Cache(60000);

  self.methodA = function methodA() {
    const cachedEntry self.cache.get('something');
    return cachedEntry;

  }
}

module.exports = MyModule;

I am only interested in controlling the return value of the get method on the cache lib for the purposes if my test cases.

My test file lives under a separate test folder in the root of my project, in my test I have attempted to use proxyquire like so:

const MyModule = proxyquire('../index.js', {
  cache: {
    get: () => {
      console.log('whoop!');
      return ('whoop!');
    },
  },
});

describe('Should attempt to retrieve a cached item', () => {
  it('should get an item successfully', () => {
    MyModule.methodA().should.equal('whoop!');
  });
});

My test fails as I get back an undefined value, since its calling out to the real cache lib. I am guessing my use of proxyquire is wrong, since my cache dependency is one level down from my top level module in index.js and so my cache stub is being ignored?

I came across this discussion about nesting proxyquire calls, but I couldnt see anything in the documentation on this.

Whats the correct approach here please?

Thanks

This should help: https://github.com/thlorenz/proxyquire#api

Proxyquire has two options:

  1. Mocking the direct deps of your module under test (recommended)
  2. Mocking a dep globally (not recommended)

You are essentially looking for a global override which are not recommended because your test no longer encapsulates the module under test because it is aware of the internals of a dependency. @global will get you your desired behavior but it's worth considering whether you could just construct a mock of ./src/index.js (i.e. your cache with a method appended) and set that directly as your stub value.

The downside to globally mocking npm packages is not too high but hopefully it's evident that if your cache module were local to the repo and was required with a relative path, a global override is very hard to reason about.