I wrote about fixing flaky test in June, here’s more discoveries over the last few months.
This time it’s mostly async-related.
Mock implementation of a hook that takes a callback, and resolves the callback asynchronously
My original implementation
1 | const mockUseTransaction = jest.fn() |
If I do not await wait(10)
, I will get a warning:
1 | Warning: Cannot update a component (`SwiperPaymentModal`) while rendering a different component (`ProcessingTransaction`). To locate the bad setState() call inside `ProcessingTransaction`, follow the stack trace as described in https://reactjs.org/link/setstate-in-render |
This is because when component is first rendered, SwiperPaymentModal
starts from processing status, and tries to render ProcessingTransaction
; When onComplete
callback is invoked synchronously, the parent (SwiperPaymentModal
) will change state via useReducer
.
Adding a wait(10)
is not exactly “flaky” as it should always pass, but the waiting time is not elegant.
Updated implementation
1 | mockUseTransaction.mockImplementationOnce( |
I don’t really need 10ms, all I need is that onComplete
is not invoked synchronously. Here we go.