2

I have a mock function that fakes a request with fetch. I want this mock function to be called with delay to check wether the timeout property in the tested function was triggered or not. I currently delay the promise like so:

   jest.useFakeTimers();

(request as jest.Mock).mockImplementationOnce(() =>
    Promise.resolve(response1).then(() => jest.advanceTimersByTime(3000))
);

In the function I am tested a config is given as a redux state if in the config a timeout property is given a setTimeOut is triggered if the request function (which we mock in the test suit is taking longer then the time out the cb of the setTimeOut should trigger and fail/error function should be trigger). The piece of code looks like this:

` return new Promise((resolve: () => void) => {
            const timeout = config.timeout || globalConfig.timeout;
            let abortTimeout: any;
            let aborted = false;
            if (timeout) {
                abortTimeout = setTimeout(
                    () => {
                        const error = new Error('Timeout');
                        console.log(timeout);
                        dispatch(apiDataFail(requestKey, error));
                        onError(error);
                        aborted = true;
                    },
                    timeout`enter code here`
                );
            }
            requestFunction(formatUrl(config.url, params), requestProperties).then(
                ({ response, body: responseBody }: HandledResponse) => {
                    if (aborted) {
                        return;
                    }

The test is looking like this:

test('The function resolves with a timeout argument', async (done) => {
    state = { apiData: getState('getData', true, {}, 'ready', 'GET', -1, undefined, undefined, 2900) };
    const resolves = await (performApiRequest('getData', {}, { data: 'json' })(dispatch, () => store.getState()))
    expect(resolves).toBeUndefined()
    const error = new Error('Timeout');
    const requestKey = getRequestKey('getData');
    expect(dispatch).toHaveBeenCalledWith(apiDataFail(requestKey, error));
    done();
});

the timeout is triggered properly but I get an error in the test: TypeError: Cannot read property 'response' of undefined

MokumJ
  • 181
  • 2
  • 9
  • 1
    My answer [here](https://stackoverflow.com/a/52196951/10149510) covers how Promises and fake timers interact. In this case it is unclear to me what you are trying to do. If you provide more context I'll help if I can. – Brian Adams Mar 12 '19 at 01:53
  • 1
    Thanks for sharing your clear and well documented answer. I am still struggling to fit my goal with the test I am writing so here is some context. The test I am writing is for the function performApiDataRequest. This function returns a promise and as an argument it has a redux state with configurations and aswell and endpoint. If certain conditions are met in the config it will trigger the request function which is also a promise(this is the mock function). I am trying to test a case when in the config a timeout is set. see next comment for example. – MokumJ Mar 12 '19 at 08:48

0 Answers0