Create a react app using Vite - Part 3
Tags: react, javascript, jest, unittest
Published: 2023-08-15 04:57:28

## Unit testing

We are going to use the most popular unit testing framework for React [Jest](https://jestjs.io/).

- Install the necessary packages

```bash
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,

```bash
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.

```bash
 touch src/setupTests.ts
```

```js
// 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.

```bash
 touch jest.config.ts
```

```javascript
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.

```bash
 touch jest.ci-config.ts
```

```js
import config from './jest.config'

export default {
  ...config,
  coverageThreshold: {},
}
```

- Create a test file for the app component and update it like the below,

```bash
touch src/app.test.tsx
```

```js
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

```bash
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

```bash
  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.

```bash
  pnpm test -- -t "add"
```

## Sample repo

The code for this series is hosted in Github [here](https://github.com/vinomanick/react-app).

Please take a look at the Github repo and let me know your feedback, and queries in the comments section.