@testing-library/react (rtl) 'waitFor' makes only success without await keyword

Viewed 1899

await waitFor() makes my test fail but waitFor() makes my test successful (without await).

The official doc said

The async methods return a Promise, so you must always use await or .then(done) when calling them. (https://testing-library.com/docs/guide-disappearance)

I don't know how can I test correctly. do I have to use rerender?

it('toggles active status', async () => {
  render(<List {...listProps} />);
  const targetItem = screen.getByRole('heading', { name: /first/i });

  // de-active color is GRAY2, active color is MINT
  expect(targetItem).toHaveStyle({ color: GRAY2 });

  // click to change the color of targetItem
  // it dispatch action that update listProps
  // So changing listProps makes <List /> re-rendering
  fireEvent.click(targetItem);

  await waitFor(() => {
    // It throws an error because the color is still GRAY2 in jest runner.
    // But, in chrome browser, it's color MINT.
    expect(targetItem).toHaveStyle({ color: MINT }); // fail
  });

  // If not use 'await' keyword, this works well.
  // jest runner knows the color is MINT
  waitFor(() => {
    expect(targetItem).toHaveStyle({ color: MINT });
  });
});
2 Answers

If I use waitFor() without await it won't fail, but also isn't truly successful.

expect statement to pass through without testing. waitFor() without await is my misconception. It's always successful even if has to fail.

Finally, I have known that test framework cannot detect results of changing props. The props are passed from Parent Component even if it is in redux store in fact.

In summary, I want to test Child Component. It gets props from Parent Component, Parent gets data to pass props from redux store.

Click event of Child fires dispatch and change store state well. But in test runner, because rendering is isolated, It was seemed to cause an error. Store state was changed but props was passed still not changed So I changed Child data structure not getting props from Parent but getting from store.

because if you are not awaiting , you are getting a promise, which is a truthy value. now if you do await and the promise resolves to a falsy value only in that case your test case will fail

Related