Skip to content

React Testing Library

Mocking non JS files

Jest doesn't understand

  • setupFilesAfterEnv
  • ['@testing-library/jest-dom/extend-expect', path.join(__dirname, 'src/test/setup')]
  • create React app: setupTests.js

moduleDirectories: [path.join(__dirname, 'src')]

  • unless you use Webpack aliases

Swap @testing-library/react with your own test utils

render

render result

  • queries

you don't need to use the result of render

Wrapper

test-utils.js
function render({ theme = "light", ...options } = {}) {
    const Wrapper = ({ children }) => (
        <ThemeProvider initialTheme="light">{children}</ThemeProvider>
    );
    return render(ui, { wrapper: Wrapper, ...options });
}

export * from "@testing-library/react";
export { render }; // use our own render

Getting DOM elements

screen

use screen instead of using queries from render

  • more resilient to changes

Which query to use

  • getByRole all the time if possible

Testing Playground

screen.debug

screen.getByRole("button", { name: /submit/i });

Only use query* to check for non-existence

expect(screen.queryByRole("alert")).not.toBeInTheDocument();

find* uses waitFor under the hood

  • use it for something that might not be available right away
const submitButton = await screen.findByRole("button", { name: /submit/i });

Mocking

const handleSubmit = jest.fn()

expect(handleSubmit).toHaveBeenCalledTimes(1)

Generate test data

faker

import faker from 'faker'
const buildLoginForm = (overrides) => {
    username: faker.internet.userName(),
    password: faker.internet.password(),
    ...overrides,
}

const {username, password} = buildLoginForm()

test-data-bot

import {build, fake} from @jackfranklin/test-data-bot

const buildLoginForm = build({
    fields: {
    username: fake(f => f.internet.userName()),
    password: fake(f => f.internet.password()),
})

const {username, password} = buildLoginForm()

test-data-bot can create sequences

Mocking Browser APIs


Last update: 2022-11-04