首页 > 解决方案 > 带有返回函数和 sinon 的存根函数?

问题描述

我想进行单元测试并覆盖我的代码,这是我的代码,如何用 sinon 覆盖 createClient ?

const client = redis.createClient({
  retry_strategy: function(options) {
    if (options.error) {
      if (options.error.code === 'ECONNREFUSED') {
        return new Error('The server refused the connection');
      }
      if (options.error.code === 'ECONNRESET') {
        return new Error('The server reset the connection');
      }
      if (options.error.code === 'ETIMEDOUT') {
        return new Error('The server timeouted the connection');
      }
    }
    if (options.total_retry_time > 1000 * 60 * 60) {
      return new Error('Retry time exhausted');
    }
    if (options.attempt > 10) {
      return undefined;
    }
    return Math.min(options.attempt * 100, 3000);
  }

标签: javascriptnode.jsredissinonstub

解决方案


您可以做的另一种方法是使用proxyquire模拟redis.createClient返回,opt以便我们可以访问retry_strategy. 在测试中,我们调用retry_strategy并通过它的options

// test.js
const proxyquire = require('proxyquire');
const src = proxyquire('./your-source-file', { 'redis': { createClient(opt) { 
  return opt 
}}});
const chai = require('chai');
const expect = chai.expect;

describe('testing redis ', function() {
  it('refuses connection', function() {
    const options = {
      error: {
        code: 'ECONNREFUSED'
      }
    }

    expect(src.retry_strategy(options).message).to.equal('The server refused the connection');            
  });
});

这是我用于测试的源文件

// source.js
const redis = require('redis');

const client = redis.createClient({
  retry_strategy: function(options) {
    if (options.error) {
      if (options.error.code === 'ECONNREFUSED') {
        return new Error('The server refused the connection');
      }
      if (options.error.code === 'ECONNRESET') {
        return new Error('The server reset the connection');
      }
      if (options.error.code === 'ETIMEDOUT') {
        return new Error('The server timeouted the connection');
      }
    }
    if (options.total_retry_time > 1000 * 60 * 60) {
      return new Error('Retry time exhausted');
    }
    if (options.attempt > 10) {
      return undefined;
    }
    return Math.min(options.attempt * 100, 3000);
  }
});

module.exports = client;

推荐阅读