Mock API Requests in React Native Testing Library with Mirage
Use your Mirage server to test your React Native app under different server scenarios using @testing-library/react-native, Jest Native, and Jest Expo.
This guide assumes your app is already set up with React Native Testing Library, Jest Native, and Expo. It should also work with both react-test-renderer and react-native-testing-library.
Step 1: Install Mirage
First, make sure you have Mirage installed:
# Using npm
npm install --save-dev miragejs
# Using Yarn
yarn add --dev miragejs
Step 2: Setup your testing environment
We'll need to update our Jest environment to work with Mirage.
First, install the polyfill for XMLHttpRequest:
# Using npm
npm install --save-dev xmlhttprequest
# Using Yarn
yarn add --dev xmlhttprequest
Then create a new jest.setup.js
file in the root of your project. We'll use this file to patch the global
variable and add support for XMLHttpRequest, self, and window.
// jest.setup.js
global.self = global
global.window = {}
global.XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest
Finally, have Jest to load the environment that we just created using jest.config.js
.
// jest.config.js
const jestPreset = require("@testing-library/react-native/jest-preset")
module.exports = {
preset: "jest-expo",
setupFiles: [...jestPreset.setupFiles],
setupFilesAfterEnv: ["./jest.setup.js"],
}
Here we're telling Jest to execute our jest.setup.js
after it sets up the test environment.
Step 3: Create a Mirage Server within a test
Within a test file, import Server
from Mirage, create a server, and mock out the API endpoints your code depends on:
// App.test.js
import React from "react"
import { render, waitForElement } from "@testing-library/react-native"
import App from "../App"
import { createServer } from "miragejs"
let server
beforeEach(() => {
server = createServer()
})
afterEach(() => {
server.shutdown()
})
it("shows the users from our server", async () => {
server.get("/users", () => [
{ id: 1, name: "Luke" },
{ id: 2, name: "Leia" },
])
const { getByTestId } = render(<App />)
await waitForElement(() => getByTestId("user-1"))
await waitForElement(() => getByTestId("user-2"))
expect(getByTestId("user-1")).toHaveTextContent("Luke")
expect(getByTestId("user-2")).toHaveTextContent("Leia")
})
When the <App />
component renders and makes a network request to /users
, Mirage will intercept and respond with the data above.
Note that we've called server.shutdown()
after each test, so that Mirage has a chance to clean itself up and not leak into other tests.
For a more complete example, check out the Mirage React Native demo on GitHub.
To learn about Mirage's powerful testing features, read the Application Testing guide.