【问题标题】:Jest test: Awating multiple promises in connected component笑话测试:在连接的组件中等待多个 Promise
【发布时间】:2017-12-03 07:01:40
【问题描述】:

我有一个连接组件 (HOC),它在 componentDidMount 中获取一些数据,例如:

function setData(data) {
  return { type: "SET_DATA", data: data };
}

function fetchData() {
  return axios.get("http://echo.jsontest.com/key/value/one/two");
}

function getData(dispatch) {
  return () => fetchData().then(response => dispatch(setData(response.data)));
}

class Welcome extends Component {
  componentDidMount() {
    this.props.getData();
  }

  render() {
    if (this.props.data) {
      return <div>We have data!</div>;
    } else {
      return <div>Waiting for data...</div>;
    }
  }
}

完整代码可以看这里:https://github.com/gylaz/react-integration-test-example/blob/eb3238c0a8aa4b15331a031d7d2d3a0aa97ef9c7/src/App.js

我的测试看起来像:

it("renders without crashing", async () => {
  axios.get = jest.fn(() => {
    return Promise.resolve({ data: { one: 1, two: 2 } });
  });
  const div = document.createElement("div");
  const component = await ReactDOM.render(<App />, div);

  expect(div.textContent).toEqual("We have data!");
});

完整的测试代码在这里:https://github.com/gylaz/react-integration-test-example/blob/eb3238c0a8aa4b15331a031d7d2d3a0aa97ef9c7/src/App.test.js

测试通过了!

但是,当我对 fetchData 方法进行修改以从响应中提取实际数据时(通过 Promise),例如:

function fetchData() {
  return axios
    .get("http://echo.jsontest.com/key/value/one/two")
    .then(response => response.data);
}

function getData(dispatch) {
  return () => fetchData().then(data => dispatch(setData(data)));
}

测试将失败,直到我在第一个 await 之前添加另一个 await

it("renders without crashing", async () => {
  axios.get = jest.fn(() => {
    return Promise.resolve({ data: { one: 1, two: 2 } });
  });
  const div = document.createElement("div");
  const component = await await ReactDOM.render(<App />, div);

  expect(div.textContent).toEqual("We have data!");
});

这是一个展示上述内容的 PR:https://github.com/gylaz/react-integration-test-example/pull/1

我的调用链中的thens 越多,我需要添加的awaits 越多,这似乎很麻烦。

有没有更好的方法在测试中同时等待所有内容,或其他解决方案?

【问题讨论】:

    标签: javascript reactjs asynchronous redux jestjs


    【解决方案1】:

    我发现而不是多个awaits 最好的事情是将期望包装在setImmediateprocess.nextTick 中。而且你不需要使用async/await

    例如:

    it("renders without crashing", () => {
      axios.get = jest.fn(() => {
        return Promise.resolve({ data: { one: 1, two: 2 } });
      });
      const div = document.createElement("div");
      const component = ReactDOM.render(<App />, div);
    
      setImmediate(() => {
        expect(div.textContent).toEqual("We have data!");
      });
    });
    

    关于 Promise 和事件外观的解释可以在 this article 中找到。

    这种方法的一个缺点是,如果期望失败,Jest 将使测试运行程序崩溃(而不是显示失败但不崩溃)。目前有一个可以在this issue on GitHub 中关注的错误。

    【讨论】:

      猜你喜欢
      • 2018-10-19
      • 2020-06-19
      • 2021-04-25
      • 2019-01-25
      • 2018-12-19
      • 2022-01-13
      • 1970-01-01
      • 2022-08-19
      • 1970-01-01
      相关资源
      最近更新 更多