Как смоделировать модульное тестирование Redis Helper любые операторы if else - PullRequest
0 голосов
/ 08 апреля 2020

У меня есть код, подобный этому

const client = redis.createClient({
      retry_strategy: function (options) {
        if (options.error) {
          if (options.error.code === 'ECONNREFUSED') {
            // End reconnecting on a specific error
            // and flush all commands with a individual errors
            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) {
          // End reconnecting after a specific timeout and flush all commands
          // with a individual error
          logger.log('redis', 'Retry time exhausted', 'error');
          return new Error('Retry time exhausted');
        }
        if (options.attempt > 10) {
          // End reconnecting with built in error
          logger.log('redis', 'Retry attempt exceed', 'error');
          return undefined;
        }
        // reconnect after
        return Math.min(options.attempt * 100, 3000);
      },
      ...config,
    });

Я провел модульное тестирование, но, видимо, не очень много обрабатывал все, как обрабатывать оператор, если как в коде выше

мой юнит-тест будет таким

sinon.stub(redis, 'createClient').resolves({err: true});
const res = await connection.createConnectionPool(config);
redis.createClient.restore();

как создать юнит-тест для этого?

1 Ответ

0 голосов
/ 09 апреля 2020

Вот решение для модульного теста:

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

...