9

I'm having issues testing my thunks, as many of my API calls are using FormData, and I can't seem to figure out how to mock this in tests. I'm using Jest.

My setup file looks like this:

import 'isomorphic-fetch';

// Mocking the global.fetch included in React Native
global.fetch = jest.fn();

// Helper to mock a success response (only once)
fetch.mockResponseSuccess = body => {
  fetch.mockImplementationOnce(() =>
    Promise.resolve({ json: () => Promise.resolve(JSON.parse(body)) })
  );
};

// Helper to mock a failure response (only once)
fetch.mockResponseFailure = error => {
  fetch.mockImplementationOnce(() => Promise.reject(error));
};

However, I get the following error on all tests that require FormData:

ReferenceError: FormData is not defined

I've tried importing the FormData file from react-native-mock, under src/Libraries/Network/FormData, but it didn't work.

So I was wondering if anyone has had any luck doing this?

In general, I'm having a hard time figuring out the best way to mock fetch requests in React Native, so any advice here would be nice. I've tried the jest-fetch-mock lib (and opened an issue about FormData), tried setting up with nock (no luck), and this plain Jest implementation, but nothing feels right yet.

devpolo
  • 2,487
  • 3
  • 12
  • 28
jhm
  • 4,379
  • 5
  • 33
  • 49

3 Answers3

22

This is an old question, but since I've found it in first page at google, here goes what I've done:

at the beginning of my test I added:

function FormDataMock() {
    this.append = jest.fn();
}
global.FormData = FormDataMock

this will make sure all places that do

const formData = new FormData()

will use my mock.

Of course, I've only mocked the 'append' method, since in my case it was the only thing I needed. The function that I was testing returned the created FormData object and I did this to test if all worked as expected:

const resultFormData = theFunction()
expect(resultFormData.append.mock.calls.sort(sortFunc)).toEqual(expected)
  • Are you able to use this solution with an installed external library that uses `FormData.append`? I've tried adding the `FormDataMock` code above to `beforeEach` in my simple test, however, I still get `FormData is not defined` from a library used within my project. Thanks. – Marklar Dec 04 '17 at 02:14
  • I tested this only with local code, not with external libraries. What is the library you tried to test? – brunovianarezende Dec 04 '17 at 10:35
  • The library is [react-native-aws3](https://github.com/benjreinhart/react-native-aws3), though I actually don't want to test it myself. It's causing my very basic test to fail, possibly just because it's a dependency in my React Native project??? – Marklar Dec 04 '17 at 20:39
  • have you tried adding the `global.FormData = ...` _before_ importing any other library? – brunovianarezende Dec 05 '17 at 11:38
  • 1
    Adding `global.FormData = ...` before importing any other library did **not** work for me. What did end up working was: `jest.mock('react-native-aws3', () => { return { Request: { FormData: {} } } });`. I'm not sure if this is the right thing to do as it appears I'll have to do it for a number of my dependencies. – Marklar Dec 07 '17 at 00:27
5

this seems working in my case:

// @ts-ignore
global.FormData = require('react-native/Libraries/Network/FormData');
Reza Babaei
  • 905
  • 1
  • 14
  • 22
2

Add the following code to beginning of your test file

global.FormData = require('FormData')

or

have something like this in your package.json

{
    "jest": {
        "preset": "react-native",
        "transformIgnorePatterns": [
          "<rootDir>/node_modules/(?!react-native|tcomb-form-native|ReactUtils|react-native-button)"
        ],
        "automock": false,
        "setupFiles": [
          "./setupJest.js"
        ]
      }
}

Then create a setupJest.js file on same folder as package.json and have following code in it

global.FormData = require('FormData')

So that jest calls the setupJest.js every time jest runs test

Susth
  • 264
  • 3
  • 11
  • the problem being that FormData (from npm) isn't the same implementation than the one in react-native. There's a "getAll" missing. – y_nk Jan 04 '22 at 05:44