在模拟调用中等待所有承诺

Wait on all promises in a simulate call

我正在使用 Jest 和 Enzyme 来测试 React 组件。

我的 React 组件(正在测试)有一个远程 select 组件。当用户键入一些文本时,将从 API 获取数据并显示选项。

test('should fetch data', () => {
  // mock the API call
  const store = require('../../src/store').default;
  store.fetchData = jest.fn(() => Promise.resolve([{ 
    id: 1, 
    name: 'someText 
  }]));

  // test
  const wrapper = shallow(<Form />);
  const remote = wrapper.find('RemoteSelect').first();
  remote.simulate('fetch', 'someText');
  expect(store.fetchData).toBeCalled();

  // more test
  remote.simulate('change', 1);
  const remoteRequeried = wrapper.find('RemoteSelect').first();
  expect(remoteRequeried.prop('label')).toBe('someText');
});

第一个测试在用户键入一些文本时从存储中获取数据。第二个测试 select 是一个选项。第二次测试失败。

很难解释这是一个 SO 问题。这些选项在 Promise 的 "then" 部分设置。 "Then" 函数在第二次模拟之前未执行。因此,当第二次模拟被触发时,选项没有被设置。

如果我在 setTimeout() 中移动第二个测试,第二个测试就会通过。

Jest 是否可以确保在执行更多测试之前执行承诺的 "then"?

你可以这样做:

test('should fetch data', () => {
  // mock the API call
  const store = require('../../src/store').default;
  let promise;
  store.fetchData = jest.fn(() => {
    promise = Promise.resolve([{ 
      id: 1, 
      name: 'someText', 
    }]);
    return promise;
  );

  // test
  const wrapper = shallow(<Form />);
  const remote = wrapper.find('RemoteSelect').first();
  remote.simulate('fetch', 'someText');
  expect(store.fetchData).toBeCalled();

  return promise.then((result) => {
    // more test
    remote.simulate('change', 1);
    const remoteRequeried = wrapper.find('RemoteSelect').first();
    expect(remoteRequeried.prop('label')).toBe('someText');
  });
});