如何在异步React组件中正确测试去抖动功能?

时间:2018-06-25 21:51:07

标签: javascript reactjs asynchronous mocha enzyme

我的react组件使用lodash debounce运行异步查询以获取一些数据-因为用户输入可能会导致重新查询,并且我想对查询进行速率限制-然后使用结果设置组件的状态返回。

我的组件(反应组件)

componentWillMount() {
  this.runQuery();
}

handler = (response) => {
   this.setState({ results: response.results });
}

runQuery = _.debounce((props = this.props) => {
  // run the query
  doStuff(mainParams)
    .withSomeOtherStuff(moreParams)
    .query()
    .then(this.handler)
    .catch((error) => {
      this.props.catchError(error);
    });
}, 200);

由于sinon-stub-promise软件包,我目前正在对主要的api出口点进行存根并获取返回承诺的数据

before((done) => {
  stub = stubGlobalFn('evaluate'); // returns stubbed promise, uses npm:sinon-stub-promise
});

这使我能够使用自定义的Reader(在其他地方测试)读取模拟响应,然后出于测试目的同步解析它。

mytest.spec.jsx

  let stub;
  const testWithProps = props => (
    new Promise((resolve, reject) => {
      new Reader(histories).readGrid((err, grid) => {
        try {
          expect(err).to.be.a('null');
          stub.resolves(grid);
          // ....

然后,在相同的testWithProps函数中,我可以将Table组件与我在测试中指定的道具一起挂载,作为某种测试工厂。

const wrapper = mount(<Table {...props} />);

在这里,我陷入了困惑,我放弃了当调用主要evaluate异步函数而不是状态处理程序时可以解决的诺言。

stub.thenable.then(() => {
  // --------------------------
  // PROBLEM: how to test without setting a timeout?
  // --------------------------
  setTimeout(() => {
    resolve(wrapper.update());
  }, 200);
  // --------------------------
  // --------------------------
});

如果要在异步行为之后测试组件 的状态,我应该在我的react组件中插入handler函数吗?我不确定如果需要的话,该如何将其分开。

最终我的测试看起来像这样:

it('toggles the row for the value when clicked', () => {
  const props = {
    // some props that I use
  };

  return testWithProps(props).then((wrapper) => {
    // simply testing that my mocked response made it in successfully to the rendered component
    expect(wrapper.state().results.length).to.equal(4);
  });
});

0 个答案:

没有答案