testing - ES6 构造函数可以更容易地用 Sinon stub 吗?

标签 testing constructor sinon es6-modules es6-class

鉴于(过于简化的)片段:

import Validator from 'validator';

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

我如何测试 Validator 是否已使用给定参数实例化? stub isValid?


我知道我可以重组我的代码来避免这个问题,我不是在寻找解决方法,因为我发现了很多(依赖注入(inject)、不使用 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);
  }
}

最佳答案

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

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

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

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

  static create(arg) {
    return new Validator(arg);
  }

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

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

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);
});

关于testing - ES6 构造函数可以更容易地用 Sinon stub 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49142026/

相关文章:

unit-testing - 测试用例是按需求、按类还是按方法?

c++ - 基于公共(public)参数调用某些类的构造函数c++

java - 为什么默认构造函数和参数化构造函数都在一个类中?

java - 了解构造函数(非常简单的代码)

javascript - Node : Testing with sinon and async/await

javascript - 如何测试需要jquery的ES6类?

azure - 选项或在 Azure 中设置测试环境

使用 APIRequestFactory : how to pass "flat" parameter to a view 进行 Django 测试

javascript - sinon 假 xhr 服务器和 polymer appLocalizeBehavior 语言环境

java - 为什么 Spring TestExecution ExceptionHandler Tests 的 ATestClass 的测试不会失败?