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 configuration docs
identity-obj-proxy
docs
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
- Transformers
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.
- When you have Provider wrappers in your app ie
jest.setup.js
import '@testing-library/jest-dom';import '@testing-library/jest-dom/extend-expect'; // needed for assertionsimport 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
- Jest CLI options
You want to see how tests are written?
While testing
You want to test Apollo graphql
- Here’s how to set it up
- Here’s a really neat way to set it up along with preliminary debugging
- Is there any way to make this easier?
- I pass my
mocks
as second argument to therender
function - I have a utility to create the mock request-response entity
- Here’s how it looks like
const {...} = render(<Component {...props}/>, MakeResponses({'query-name': {params: // query params go here,data: // response goes here},...}))
- I pass my
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
- Globals Object
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
- Jest Mocks
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