Reputation: 31
Problem
I'm using redux-saga, jest, redux-mock-store and react-testing-library, I try to test a saga that makes polling to the server until the status of the response is resolved. In the saga i'm using the redux-saga delay function to create an interval of the polling.
const INTEVAL_TIME = 3000;
function* saga(action) {
try {
yield delay(INTEVAL_TIME);
while (true) {
const { data } = yield call(apiCall);
if (data.status === 'success') {
yield put(success());
break;
}
if (data.status === 'failure') {
yield put(failure());
break;
}
yield delay(INTEVAL_TIME );
}
} catch (error) {
yield put(failure());
}
}
how can i in the test it self mock the delay to not wait 3 sec (maybe setting the delay to 0 or resolve immediately). for example, this is my test
it('some test', async () => {
const { getByTestId } = render(<MyComponent />);
userEvent.click(getByTestId('button');
await waitFor(() => {
expect(store.getActions()).toEqual(succesPayloadMock);
});
});
Upvotes: 3
Views: 1432
Reputation: 1377
I'm not sure if I fully understand your question but when it comes to redux saga I use the library redux-saga-test-plan and to integrate a delay mock I do the following:
const provideDelay = ({ fn }: FnObj, next: () => void) =>
fn.name === "delayP" ? null : next();
return expectSaga(function)
.provide([{ call: provideDelay }])
.call(anotherFunction)
.run();
Upvotes: 2
Reputation: 516
The solution to this problem is actually discussed in Beginner Tutorial of redux-saga here. Put briefly, you want to yield a call effect instead of calling delay directly.
Upvotes: 0