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

MyComponent (反应成分)

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

我目前正在删除我的主要api退出点,该数据输出并获取数据,这要归功于 sinon-stub-promise

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 async函数而不是状态处理程序时解析的promise .

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

如果我想在异步行为之后测试组件的状态,我应该在反应组件内部存储我的 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);
  });
});