简体   繁体   中英

Testing an inside function with sinon

I need to test a function called "cache". It is a function wrapper, which takes a function and caches its results depending on the arguments, that were applied to the function.

This is how I implemented the function

const cache = (func) => {
    let cache = {};
    let stringFromArgs;
    return (...args) => {
        let n = args[0];
        if (stringFromArgs === JSON.stringify(args)) {
           return cache[n];
        } else  {
            stringFromArgs = JSON.stringify(args)
            cache[n] = func(...args);
            return cache[n];
        }
    }
}

So this is how it works:

let complexFunction = function(arg1, arg2) {
    return arg1 + arg2;
 };



let cachedFunction = cache(complexFunction);


cachedFunction(1, 2); // complex function should be executed
cachedFunction(1, 2); // complex function should not be invoked again,
                      // instead the cached result should be returned
cachedFunction(1, 5); // should be executed, because the method wasn't invoked before with these arguments

When the function cachedFunction is called twice with the same arguments, that inside function should be called only once. Second time the result should come from the cache. I need to test that using sinon.js. Or maybe there is another way to test that?

Here is the unit test solution:

cache.js :

const cache = (func) => {
  let cache = {};
  let stringFromArgs;
  return (...args) => {
    let n = args[0];
    if (stringFromArgs === JSON.stringify(args)) {
      return cache[n];
    } else {
      stringFromArgs = JSON.stringify(args);
      cache[n] = func(...args);
      return cache[n];
    }
  };
};

module.exports = cache;

cache.test.js :

const cache = require('./cache');
const sinon = require('sinon');
const { expect } = require('chai');

describe('62426207', () => {
  it('should call complex function', () => {
    let complexFunction = sinon.stub().callsFake((arg1, arg2) => {
      return arg1 + arg2;
    });
    let cachedFunction = cache(complexFunction);
    cachedFunction(1, 2);
    sinon.assert.calledWith(complexFunction, 1, 2);
    sinon.assert.calledOnce(complexFunction);
  });

  it('should not call complex function again', () => {
    let complexFunction = sinon.stub().callsFake((arg1, arg2) => {
      return arg1 + arg2;
    });
    let cachedFunction = cache(complexFunction);
    cachedFunction(1, 2);
    let ret = cachedFunction(1, 2);
    expect(ret).to.be.equal(3);
    sinon.assert.calledWith(complexFunction, 1, 2);
    sinon.assert.calledOnce(complexFunction);
  });

  it('should call complex function if arguments are different', () => {
    let complexFunction = sinon.stub().callsFake((arg1, arg2) => {
      return arg1 + arg2;
    });
    let cachedFunction = cache(complexFunction);
    let ret1 = cachedFunction(1, 2);
    expect(ret1).to.be.equal(3);
    let ret2 = cachedFunction(1, 5);
    expect(ret2).to.be.equal(6);
    sinon.assert.calledWith(complexFunction, 1, 2);
    sinon.assert.calledWith(complexFunction, 1, 5);
    sinon.assert.calledTwice(complexFunction);
  });
});

unit test result with 100% coverage:

  62426207
    ✓ should call complex function
    ✓ should not call complex function again
    ✓ should call complex function if arguments are different


  3 passing (18ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |     100 |      100 |     100 |     100 |                   
 cache.js |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM