Unit testing
We are going to use the most popular unit testing framework for React Jest.
- Install the necessary packages
pnpm add -D jest @types/jest ts-jest ts-node
pnpm add -D @testing-library/react jest-environment-jsdom
pnpm add -D @testing-library/jest-dom @types/testing-library__jest-dom
Package | Purpose |
---|---|
jest | Test runner |
ts-jest | For running jest in typescript supported app. |
ts-node | For creating jest config file in ts extension |
jest-environment-jsdom | For running jsdom in jest react app |
@testing-library/react | React testing library |
@testing-library/jest-dom | React testing library dom assertions support |
@types/jest, @types/testing-library__jest-dom | Types library for Jest and Jsdom |
- Jest runs our test in a simulated DOM environment so the style imports and SVG imports will throw an error. Those imports will not add any value in the test environment so 'Jest' team recommends we mock those imports. so create a mocks folder in the root directory with mock files for SVG and style imports as below,
mkdir __mocks__
echo "export {};" > __mocks__/style.ts
echo "export default 'SvgrURL';\nexport const ReactComponent = 'div';" > __mocks__/svg.ts
- Create the
src/setupTests.ts
file and update it with the below content.
touch src/setupTests.ts
// This import will add the DOM related assertions support to the expect statement.
import '@testing-library/jest-dom'
beforeAll(() => {
// Add your global beforeAll logics
})
beforeEach(() => {
// Add your globalbeforeEach logics
})
afterAll(() => {
// Add your global afterAll logics
})
afterEach(() => {
// Add your global afterEach logics
})
- Create the jest.config.ts file and update it with the below config.
touch jest.config.ts
export default {
preset: 'ts-jest',
testEnvironment: 'jsdom',
moduleNameMapper: {
'\\.svg$': '<rootDir>/__mocks__/svg.ts',
'^.+\\.css': '<rootDir>/__mocks__/style.ts',
'^src/(.*)$': '<rootDir>/src/$1',
},
setupFilesAfterEnv: ['<rootDir>/src/setupTests.ts'],
modulePathIgnorePatterns: ['./dist/'],
coveragePathIgnorePatterns: [],
collectCoverageFrom: ['./src/**/*.ts', '!./src/**/*.test.ts'],
coverageThreshold: {
global: {
branches: 100,
functions: 100,
lines: 100,
statements: 100,
},
},
}
- Create the jest.ci-config.ts file and update it with the below config.
touch jest.ci-config.ts
import config from './jest.config'
export default {
...config,
coverageThreshold: {},
}
- Create a test file for the app component and update it like the below,
touch src/app.test.tsx
import { render, screen } from '@testing-library/react'
import { App } from './app'
describe('Component | App', () => {
it('should render the app component', async () => {
render(<App />)
expect(screen.getByText('Rendered from react app')).toBeInTheDocument()
})
})
- Update the package scripts for running tests
npm pkg set scripts.test="jest"
npm pkg set scripts.test:coverage="jest --coverage"
npm pkg set scripts.test:ci="jest --coverage --config='./jest.ci-config.ts'"
- Run the tests
pnpm test
If you face the below issue while running the test, add the esModuleInterop
prop and set it to true
in your tsconfig.json file.
If you have issues related to imports, you should consider setting `esModuleInterop` to `true` in your TypeScript configuration file (usually `tsconfig.json`). See https://blogs.msdn.microsoft.com/typescript/2018/01/31/announcing-typescript-2-7/#easier-ecmascript-module-interoperability for more information.
- To run a particular test use the -t param.
pnpm test -- -t "add"
Sample repo
The code for this series is hosted in Github here.
Please take a look at the Github repo and let me know your feedback, and queries in the comments section.
Top comments (0)