Search code examples
node.jstestingmocha.jssinonchai

How to stub node-cache's cache.get()?


I'm writing a unit test for a function that uses node-cache. At the following function,

  1. I want to have a string return at the first cache.get
  2. an array in the second cache.get

Please note that I removed some parts of code from testFunction since it is not relavant to my question.

const NodeCache          = require('node-cache');
const cache              = new NodeCache();
...
const testFunction = () => {
  let myStringCache = cache.get('cacheName1');
  let myArrayCache = cache.get('cacheName2');

   ... Do something with caches ...

   return 'return something';
}

...
module.exports = {
   ...,
   testFunction,
   ...
}

I created the following test

describe('sample test with testFunction() ', ()=>{
  let stubCache;
  let stub;
  before((done)=>{
    sandbox = sinon.createSandbox();
    stubCache = sandbox.stub(cache, 'get');
    stubCache.withArgs('cacheName1').returns('sample string');
    stubCache.withArgs('cacheName2').returns([1,2,3,4,5,6]);
    stub = proxyquire('./filelocation.js',{
      'node-cache': stubCache
    });
    done();
  });

  it('should not throw error',(done)=>{
    chai.expect(stub.testFunction()).not.to.throw;
  });
})

I was Googling around, and there is some partial solution to use proxyquire to stub the value. but looks like it does stub but it's not where I wanted. It stubs at NodeCache but cache

So I have questions:

  1. Does anybody know how to stub cache.get() with mocha, chai or sinon? If so, please share how you do it ?
  2. Is it possible to stub different returns by the argument of cache.get()?

Solution

  • Here is the unit test solution:

    index.js:

    const NodeCache = require("node-cache");
    const cache = new NodeCache();
    
    const testFunction = () => {
      let myStringCache = cache.get("cacheName1");
      let myArrayCache = cache.get("cacheName2");
      console.log("myStringCache:", myStringCache);
      console.log("myArrayCache:", myArrayCache);
      return "return something";
    };
    
    module.exports = {
      testFunction
    };
    

    index.spec.js:

    const sinon = require("sinon");
    const proxyquire = require("proxyquire");
    const chai = require("chai");
    
    describe("sample test with testFunction() ", () => {
      let stubCache;
      let stub;
      let getCacheStub;
      before(() => {
        sandbox = sinon.createSandbox();
        getCacheStub = sandbox.stub();
        stubCache = sandbox.stub().callsFake(() => {
          return {
            get: getCacheStub
          };
        });
        getCacheStub.withArgs("cacheName1").returns("sample string");
        getCacheStub.withArgs("cacheName2").returns([1, 2, 3, 4, 5, 6]);
        stub = proxyquire("./", {
          "node-cache": stubCache
        });
      });
    
      it("should not throw error", () => {
        const logSpy = sinon.spy(console, "log");
        chai.expect(stub.testFunction()).not.to.throw;
        sinon.assert.calledWith(
          logSpy.firstCall,
          "myStringCache:",
          "sample string"
        );
        sinon.assert.calledWith(logSpy.secondCall, "myArrayCache:", [
          1,
          2,
          3,
          4,
          5,
          6
        ]);
      });
    });
    

    Unit test result with 100% coverage:

      sample test with testFunction() 
    myStringCache: sample string
    myArrayCache: [ 1, 2, 3, 4, 5, 6 ]
        ✓ should not throw error
    
    
      1 passing (87ms)
    
    ---------------|----------|----------|----------|----------|-------------------|
    File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
    ---------------|----------|----------|----------|----------|-------------------|
    All files      |      100 |      100 |      100 |      100 |                   |
     index.js      |      100 |      100 |      100 |      100 |                   |
     index.spec.js |      100 |      100 |      100 |      100 |                   |
    ---------------|----------|----------|----------|----------|-------------------|
    

    Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/58278211