javascriptreactjsjestjs

Testing FormData submitted to fetch using jest


I'm using Jest to test calling an API in my React app.

The code I'm testing is:

const createItem = (data) => {
  let formData = buildForm(data);

  return fetch(URL, {
    method: 'POST',
    body: formData
  });
};

I want to confirm that the buildForm function correctly converts the data to a FormData object.

My test looks like this:

it('creates item using api', () => {
  let data = {name: 'test name'};
  return createItem(data)
    .then(() => {
      let expForm = new FormData();
      expForm.append('name', data.name);

      expect(global.fetch).toHaveBeenCalledWith(URL, {
        method: 'POST',
        body: expForm
      });
    });
});

The problem is, this test passes regardless what fields I append to expForm in my test. It seems like toHaveBeenCalledWith doesn't actually compare the values of body and just checks that it is a FormData object.

How can I test the values passed into the body FormData object?


Solution

  • You can convert the FormData entries into an object for easy comparison.

    expect(global.fetch).toHaveBeenCalledWith(
      URL,
      expect.objectContaining({ method: 'POST', body: expect.any(FormData) })
    );
    
    const formData = Array.from(global.fetch.calls[0][1].body.entries())
      .reduce((acc, f) => ({ ...acc, [f[0]]: f[1] }), {});
    expect(formData).toMatchObject(data);