yoni aizenshteiin
yoni aizenshteiin

Reputation: 31

Mocking saga delay in jest

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

Answers (2)

thodwris
thodwris

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

matej bobaly
matej bobaly

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

Related Questions