How to make sure onUploadProgress callback inside axios call is getting covered in unit test

Viewed 436

I'm making an api call through axios in reactjs to upload files on server. I' using onUploadProgress callback inside axios to track and show progress of upload on UI.

But i'm having hard time to cover onUploadProgress callback in my jest unit test case. I'm able to mock axios call and return the resolved promise with mock response but in my test coverage it shows that all lines written inside onUploadProgress callback are not covered.

Somehow i need to make sure everything inside onUploadProgress callback is being covered in my test case. It could be through changing mock implementation of axios or mocking parameters/config being passed as input to axios, but not able to figure it out.

Below is my actual api logic

export async function uploadAttachmentsApi(files: any[], progress: number[], setProgress: Function): Promise<string[]> {
  const apiUrl = 'some api url';
  const promises: any = [];
  const uploadProgress: number[] = [];

  for (let x = 0; x < files.length; x += 1) {
    const data = new FormData();
    data.append('file', files[x]);

    const promise = axiosApi(apiUrl, {
      method: 'post',
      data,
      onUploadProgress: (progressEvent) => {
        uploadProgress[x] = Math.round((100 * progressEvent.loaded) / progressEvent.total);
        setProgress([...uploadProgress, ...progress]);
      },
    });

    promises.push(promise);
  }

  return Promise.all(promises);
}

Below is my unit test case for above code

describe('upload-attachment-api', () => {
  it('uploadAttachments should make post call', async () => {
    const files: any[] = [
      {
        name: 'file1.doc',
        size: '1024',
        type: 'txt/plain',
        lastModifiedOn: new Date('2021-05-03'),
      },
    ];
    const urls = ['C:\\EmailAttachments\\154\\file1.doc', 'C:\\EmailAttachments\\154\\file2.pdf'];
    const progress = [100];
    const setProgress = jest
      .fn()
      .mockImplementationOnce((uploadProgress: number[]) => [...uploadProgress, ...progress]);
    const axiosCall = jest.spyOn(common, 'axiosApi').mockImplementationOnce(() => Promise.resolve(urls));

    const result = await uploadAttachmentsApi(files, progress, setProgress);

    expect(axiosCall).toBeCalled();
    expect(result[0]).toEqual(urls);
  });
});

Note: axiosApi i'm using above for api call is a wrapper on top of actual axios package created by my organization. So i can't directly mock axios package or use AxiosMockAdapter for the same.

Here is a sneek peek on axiosApi wrapper

function axiosApi(url, options) {
  var modifiedOptions = options || {};
  modifiedOptions.url = url;
  modifiedOptions.headers.Authorization = //Bearer token from common redux store received from company's SSO
  return axios.request(modifiedOptions).then(function (response) {
    return response.data;
  });
}

Appreciate any help

0 Answers
Related