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

Terminal window
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>);
}

← Back to notes