我需要测试一个叫做 "cache "的函数。它是一个函数包装器,它接受一个函数,并根据应用于该函数的参数来缓存其结果。
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];
}
}
}
所以这就是工作原理。
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
当函数cachedFunction被调用两次,参数相同时,里面的函数应该只被调用一次。第二次的结果应该来自于缓存。我需要用sinon.js来测试。或者有其他方法可以测试吗?
这是单元测试的解决方案。
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);
});
});
单元测试结果100%覆盖。
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 |
----------|---------|----------|---------|---------|-------------------