vijayst
vijayst

Reputation: 21836

Wait on all promises in a simulate call

I am using Jest and Enzyme to test React components.

My React component (under test) has a remote select component. When the user types some text, data is fetched from API and the options are displayed.

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

The first test fetches data from the store when user types some text. The second test selects an option. The second test fails.

It is a difficult to explain this is an SO question. The options are set in the "then" part of the Promise. "Then" function is not getting executed before the second simulate. So, the options are not set when the second simulate is fired.

If I move the second test within a setTimeout(), the second test passes.

Is there anyway for Jest to ensure the "then" of the promise gets executed before performing more tests?

Upvotes: 2

Views: 779

Answers (1)

Brigand
Brigand

Reputation: 86220

You could do something like this:

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

Upvotes: 1

Related Questions