Вот решение для модульного теста:
index.js
:
const redis = require('redis');
const logger = {
log: console.log,
};
const client = redis.createClient({
retry_strategy: function(options) {
if (options.error) {
if (options.error.code === 'ECONNREFUSED') {
logger.log('redis', 'The server refused the connection', 'error');
return new Error('The server refused the connection');
}
if (options.error.code === 'ECONNRESET') {
logger.log('redis', 'The server reset the connection', 'error');
return new Error('The server reset the connection');
}
if (options.error.code === 'ETIMEDOUT') {
logger.log('redis', 'The server timeouted the connection', 'error');
return new Error('The server timeouted the connection');
}
}
if (options.total_retry_time > 1000 * 60 * 60) {
logger.log('redis', 'Retry time exhausted', 'error');
return new Error('Retry time exhausted');
}
if (options.attempt > 10) {
logger.log('redis', 'Retry attempt exceed', 'error');
return undefined;
}
return Math.min(options.attempt * 100, 3000);
},
});
module.exports = client;
index.test.js
:
const sinon = require('sinon');
const redis = require('redis');
describe('61096134', () => {
let logSpy;
beforeEach(() => {
logSpy = sinon.spy(console, 'log');
});
afterEach(() => {
sinon.restore();
delete require.cache[require.resolve('./')];
});
it('should return an error if server refused the connection', () => {
const options = { error: { code: 'ECONNREFUSED' } };
let returnValue;
const createClientStub = sinon.stub(redis, 'createClient').callsFake((clientOpts) => {
returnValue = clientOpts.retry_strategy(options);
});
require('./');
sinon.assert.match(returnValue.message, 'The server refused the connection');
sinon.assert.calledWithExactly(createClientStub, { retry_strategy: sinon.match.func });
sinon.assert.calledWithExactly(logSpy, 'redis', 'The server refused the connection', 'error');
});
it('should return an error if server reset the connection', () => {
const options = { error: { code: 'ECONNRESET' } };
let returnValue;
const createClientStub = sinon.stub(redis, 'createClient').callsFake((clientOpts) => {
returnValue = clientOpts.retry_strategy(options);
});
require('./');
sinon.assert.match(returnValue.message, 'The server reset the connection');
sinon.assert.calledWithExactly(createClientStub, { retry_strategy: sinon.match.func });
sinon.assert.calledWithExactly(logSpy, 'redis', 'The server reset the connection', 'error');
});
it('should return an error if server timeouted the connection', () => {
const options = { error: { code: 'ETIMEDOUT' } };
let returnValue;
const createClientStub = sinon.stub(redis, 'createClient').callsFake((clientOpts) => {
returnValue = clientOpts.retry_strategy(options);
});
require('./');
sinon.assert.match(returnValue.message, 'The server timeouted the connection');
sinon.assert.calledWithExactly(createClientStub, { retry_strategy: sinon.match.func });
sinon.assert.calledWithExactly(logSpy, 'redis', 'The server timeouted the connection', 'error');
});
it('should return an error if retry time exhausted', () => {
const options = { total_retry_time: 1000 * 60 * 61 };
let returnValue;
const createClientStub = sinon.stub(redis, 'createClient').callsFake((clientOpts) => {
returnValue = clientOpts.retry_strategy(options);
});
require('./');
sinon.assert.match(returnValue.message, 'Retry time exhausted');
sinon.assert.calledWithExactly(createClientStub, { retry_strategy: sinon.match.func });
sinon.assert.calledWithExactly(logSpy, 'redis', 'Retry time exhausted', 'error');
});
it('should return undefined if retry attempt exceed', () => {
const options = { attempt: 11 };
let returnValue;
const createClientStub = sinon.stub(redis, 'createClient').callsFake((clientOpts) => {
returnValue = clientOpts.retry_strategy(options);
});
require('./');
sinon.assert.match(returnValue, undefined);
sinon.assert.calledWithExactly(createClientStub, { retry_strategy: sinon.match.func });
sinon.assert.calledWithExactly(logSpy, 'redis', 'Retry attempt exceed', 'error');
});
it('should return retry stragegy', () => {
const options = { attempt: 5 };
let returnValue;
const createClientStub = sinon.stub(redis, 'createClient').callsFake((clientOpts) => {
returnValue = clientOpts.retry_strategy(options);
});
require('./');
sinon.assert.match(returnValue, 500);
sinon.assert.calledWithExactly(createClientStub, { retry_strategy: sinon.match.func });
});
});
Результаты модульного теста с отчетом о покрытии:
61096134
redis The server refused the connection error
✓ should return an error if server refused the connection (945ms)
redis The server reset the connection error
✓ should return an error if server reset the connection
redis The server timeouted the connection error
✓ should return an error if server timeouted the connection
redis Retry time exhausted error
✓ should return an error if retry time exhausted
redis Retry attempt exceed error
✓ should return undefined if retry attempt exceed
✓ should return retry stragegy
6 passing (1s)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 91.67 | 100 | 100 |
index.js | 100 | 91.67 | 100 | 100 | 18
----------|---------|----------|---------|---------|-------------------
исходный код: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/61096134