index

React Testing Recipes

You want to setup jest

A minimal config

jest.config.js

module.exports = {
 transform: {
   "^.+\\.jsx?$": `<rootDir>/jest-preprocess.js`,
 },
 moduleNameMapper: {
   '^.+\\.(css|style|less|sass|scss)$': 'identity-obj-proxy',
 },
 transformIgnorePatterns: [ '!node_modules/',],
 testEnvironmentOptions: {
   url: `http://localhost`,
 },
}

Further Reading

jest.preprocess.js

const babelOptions = {
  // your babel config goes here
};

module.exports = require('babel-jest').default.createTransformer(babelOptions);

Further Reading

You want coverage reports

jest.config.js

module.exports = {
...
 collectCoverage: true,
 coverageDirectory: 'coverage',
 reporters: ['default', ['jest-junit', { outputDirectory: 'reports' }]],
...
}

Further reading

You want to enable/add path alias support

jest.config.js

const { pathsToModuleNameMapper } = require('ts-jest');
const { compilerOptions } = require('./jsconfig.json'); // or tsconfig.json

const paths = pathsToModuleNameMapper(compilerOptions.paths, {
  prefix: '<rootDir>/',
});

module.exports = {
...
    moduleNameMapper: {
        ...paths,
        // other path aliases you want to add manually
    }
    ...
}

Your project uses other file extensions ie svg/gql/…

You need transformers Here’s how you would add transformers for .gql & .svg files. You will need to add them as dev dependencies.

jest.config.js

module.exports = {
...
  transform: {
    '\\.(gql|graphql)$': '@graphql-tools/jest-transform',
    '^.+\\.svg$': 'jest-transformer-svg',
    ...
  },
...}

Further Reading

Setup file

  • Why you need this?
    • When you have Provider wrappers in your app ie SnackbarProvider, ThemeProviders, you might need to setup a custom render function which automatically wraps your Component to be tested with the necessary wrappers.

jest.setup.js

import '@testing-library/jest-dom';
import '@testing-library/jest-dom/extend-expect'; // needed for assertions
import React from 'react';
import { render } from '@testing-library/react';
// import all your Providers here

const AllTheProviders = ({ children }) => {
  return <Provider>{children}</Provider>;
};

const customRender = (ui, options) =>
  render(ui, { wrapper: AllTheProviders, ...options });

export * from '@testing-library/react';

export { customRender as render };

You want to run jest

npx jest

Add it as a script to package.json package.json

{
  "scripts": {
    "test": "jest"
  }
}

Further Reading

You want to see how tests are written?

While testing

You want to test Apollo graphql

You want to simulate browser events - Click/Change/…

You are facing SOME_ENV_VAR not defined

You can define global variables by jest.config.js

module.exports = {
  ...,
  globals: {
    ENV_VAR_NAME: VALUE
  },
  ...
}

Further Reading

You want to mock

You want to mock a npm dependency

If the dependency is a commonjs module, you can do

jest.mock('dependency', () => ({
  default: jest.fn(),
}));

Assuming the dependency is exported as default

  • For named exports, you can do
jest.mock('dependency', () => ({
  namedExportedFunction: jest.fn(),
}));
  • If the dependency is es6 module, you can do
jest.mock('dependency', () => ({
  __esModule: true,
  default: jest.fn(),
  namedExportedFunction: jest.fn(),
}));

Further Reading

You want to mock a Component

For example, You want to mock Route to bypass authentication. Assuming you have the following folder structure and Route is the default export

...
|-Route
  |- index.js

You can add the Route mock at Route/__mocks__/index.js

Route/mocks/index.js

function MockRoute({children}) {
  return (
    <>{children}</>
  );
};

Route can be automatically mocked by placing the following snippet in your test file

jest.mock('path/to/Route');

You want to mock a Context

AuthProvider has the following state

const AuthContext = React.createContext({
  user: null,
  login: () => {},
  logout: () => {},
});

You can mock AuthProvider by AuthProvider/mocks/index.js

const AuthContext = React.createContext();
const AuthState = {
  user: null,
  login: jest.fn(),
  logout: jest.fn(),
};

export default function AuthProvider(){
  return (<AuthContext.Provider value={{
    user: null,
    login: () => {},
    logout: () => {},
  }}>
    {children}
  </AuthContext.Provider>);
}