nbpeth
nbpeth

Reputation: 3148

Redux Saga Test Plan - Stub different responses for provided calls

I've got a saga that has some error handling logic in it - I want to test that a call is made three times and provide a response for each invocation. The use case is that the saga retries on the first two errors before giving up, so I need a sequence of response: [fail, fail, success]

it("must succeed after the first two requests are failures", () =>
      expectSaga(
        sagaToTest
      ).provide([
          [
            call(getdata, request),
            throwError(new Error("oops")) // do this twice and succeed on the third invication
          ]
        ])
        .call(getdata, request)
        .call(getdata, request)
        .call(getdata, request)
        .put(actions.itSucceeded("message"))
        .run());
  });

This is straightforward in other testing / mocking libraries but for some reason I can't seem to find the right documentation.

Thanks!

Upvotes: 1

Views: 905

Answers (1)

user18746560
user18746560

Reputation: 1

This library does exactly that https://www.npmjs.com/package/saga-test-stub

You'll need to split your code tho, first encapsulate the throwable call in a separate saga and test it

function* callApi(request: any){
    try {
        const response = call(getdata, request);
        return {sucess:true,response}
    }
    catch (e){
        return {sucess:false}
    }
}

describe('callApi saga', () => {
    let sagaStub: SagaStub;
    beforeEach(() => {
        sagaStub = stub(callApi, {});
    });
    describe('when call to api fails', () => {
        beforeEach(() => {
            jest.spyOn(api,'callApi').mockImplementation(()=> {
                throw new Error()
            });
            it('should return success false', () => {
                expect(saga).toBeDone({sucess:false})
            });
        });
    });
    describe('when call to api works', () => {
        // ...
    });
});

then stub the yielded values from the first saga

describe('sagaToTest', () => {
    let sagaStub: SagaStub;
    beforeEach(() => {
        sagaStub = stub(sagaToTest, {});
        when(sagaStub).yields(call(callApi,{})).doNext(
            {succes: false},
            {succes: false},
            {succes: true, response: 'here you go'},
        )
    });

    it('must succeed after the first two requests are failures', () => {
        expect(sagaStub).toYield(
            call(callApi,{}), //note: this is redundant since it is stubbed
            call(callApi,{}), //note: this is redundant since it is stubbed
            call(callApi,{}), //note: this is redundant since it is stubbed
            put(actions.itSucceeded("message"))
        )
    });
});

Upvotes: 0

Related Questions