【问题标题】:Can ES6 constructors be stubbed more easily with Sinon?ES6 的构造函数可以用 Sinon 更容易地存根吗?
【发布时间】:2018-03-07 00:02:39
【问题描述】:

鉴于(过于简化的)sn-p:

import Validator from 'validator';

export default function isValid(arg) {
  // Validator#isValid is an ES6 getter
  return new Validator(arg).isValid;
}   

如何测试Validator 是用给定参数实例化的?还有存根isValid?


我知道我可以重组我的代码来避免这个问题,我不是在寻找解决方法,因为我发现了很多(依赖注入,不使用 ES6 糖等)。

我找到了一种方法,但它非常难看。在测试文件中:

import ValidatorNamespace from 'validator';

const Validator = ValidatorNamespace.default;
let validatorInstance;
let validatorConstructor;

const subject = arg => isValid(arg);
const validityStatus = true;

describe('isValid helper', () => {
  beforeEach(() => {
    validatorInstance = sinon.createStubInstance(Validator);

    // Yay! This is how I managed to spy on the constructor!.. :(
    validatorConstructor = sandbox.stub(ValidatorNamespace, 'default').
      returns(validatorInstance);

    sandbox.stub(validatorInstance, 'isValid').value(validityStatus);
  });

  it('instantiates the validator properly', ()=> {
    subject('arg');
    expect(validatorConstructor).to.have.been.calledWith('arg')
  });

  it('returns the value returned by the validator', ()=> {
    expect(subject('arg')).to.eq(validityStatus);
  });
});

验证码:

export default class Validator {
  constructor(arg) {
    this.innerValue = arg;
  }

  get isValid() {
    return aFunctionOf(this.innerValue);
  }
}

【问题讨论】:

    标签: testing constructor sinon es6-modules es6-class


    【解决方案1】:

    你想要的实际上是不可能的。存根需要某种“接缝”,通过它将存根放置到位。当您直接在生产代码中导入函数(构造函数或其他)时,您留下的唯一接缝就是导入过程本身。

    proxyquire,它覆盖了节点中的require 调用。我不知道你使用的是什么环境,我真的不知道这与 ES6 模块的配合如何。但是,如果您使用 babel 转译为 ES6,它应该可以工作。

    根据我的经验,这种东西不值得额外的复杂性。我通常的解决方法是只制作一个静态工厂函数并存根/使用它,而不是直接使用构造函数:

    export default class Validator {
      constructor(arg) {
        this.innerValue = arg;
      }
    
      static create(arg) {
        return new Validator(arg);
      }
    
      get isValid() {
        return aFunctionOf(this.innerValue);
      }
    }
    

    如果你想对工厂进行单元测试,你可以简单地检查返回的实例而不是存根构造函数:

    it('create should return an instance', function() {
      let arg = { foo: 'bar' };
    
      let result = Validator.create(arg);
    
      expect(result).to.be.an.instanceof(Validator);
      expect(result.innerValue).to.equal(arg);
    });
    

    【讨论】:

      猜你喜欢
      • 2018-06-18
      • 1970-01-01
      • 2017-06-29
      • 2016-09-17
      • 1970-01-01
      • 2015-06-04
      • 2016-03-31
      • 2021-04-14
      • 1970-01-01
      相关资源
      最近更新 更多