DEV Community

Cover image for Mastering Jest Configuration for React TypeScript Projects with Vite: A Step-by-Step Guide
shubhambajaj
shubhambajaj

Posted on

Mastering Jest Configuration for React TypeScript Projects with Vite: A Step-by-Step Guide

1. First generate react typescript using vite

npm create vite@latest
Enter fullscreen mode Exit fullscreen mode

2. Install dependancies

npm i jest @types/jest ts-jest --save-dev
Enter fullscreen mode Exit fullscreen mode

3. Exclude test files from typescript type checking for production

  • Create tsconfig.prod.json and paste following contents into it.
touch tsconfig.prod.json
Enter fullscreen mode Exit fullscreen mode
// tsconfig.prod.json
{
  "extends": "./tsconfig",
  "exclude": [
    "./src/__tests__/**",
    "./src/__mocks__/**",
    "./src/test-utils"
  ]
}

Enter fullscreen mode Exit fullscreen mode

Exclude test files from typescript type checking when building for production, you don’t want a typescript error in your test file breaks your build in production.

—Nguyen Viet Hung, hung.dev
  • Use tsconfig.prod.json when building
# package.json
{
...,
"scripts":{
  ...,
  "build": "NODE_ENV=production tsc -p tsconfig.prod.json && vite build"
},
...
}
Enter fullscreen mode Exit fullscreen mode

4. Add test script to package.json

// package.json
{
...,
"scripts":{
  ...,
  "test": "NODE_ENV=test jest"
},
...
}
Enter fullscreen mode Exit fullscreen mode

5. Write a simple test

// src/App.test.tsx

describe('App', () => {
  it('should work as expected', () => {
    expect(1 + 1).toBe(2);
  });
});
Enter fullscreen mode Exit fullscreen mode

Run the npm run test 🤞, and first test case 😃 passed. 🚀

node 'node_modules/.bin/jest' '/.../code/my-doc-test-app/src/App.test.tsx' -t 'App'
 PASS  src/App.test.tsx
  App
    ✓ should work as expected (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.209 s
Ran all test suites matching /...\/code\/my-doc-test-app\/src\/App.test.tsx/i with tests matching "App".

Enter fullscreen mode Exit fullscreen mode

6. Test the App component

// src/App.test.tsx
import { render } from '@testing-library/react';
import App from './App';

describe('App', () => {
  it('should work as expected', () => {
    render(<App />);
  });
});
Enter fullscreen mode Exit fullscreen mode

Run the npm run test 🤞, and test failed. This error will show up.

node 'node_modules/.bin/jest' '/Users/satparkash/code/test-app/src/A
pp.test.tsx' -t 'App'
 FAIL  src/App.test.tsx
  ● Test suite failed to run

    SyntaxError: /Users/satparkash/code/test-app/src/App.test.tsx: Support for the experimental syntax 'jsx' isn't currently enabled (6:12):

      4 | describe('App', () => {
      5 |   it('should work as expected', () => {
    > 6 |     render(<App />);
        |            ^
      7 |   });
      8 | });
      9 |

    Add @babel/preset-react (https://github.com/babel/babel/tree/main/packages/babel-preset-react) to the 'presets' section of your Babel config to enable transformation.
    If you want to leave it as-is, add @babel/plugin-syntax-jsx (https://github.com/babel/babel/tree/main/packages/babel-plugin-syntax-jsx) to the 'plugins' section to enable parsing.

    Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.278 s
Ran all test suites matching /\/Users\/satparkash\/code\/test-app\/src\/App.test.tsx/i with tests matching "App".

Enter fullscreen mode Exit fullscreen mode

The above ☝️ error message is indicating a syntax related to JSX in test file.
The error is saying that support for the syntax 'JSX' isn't currently enabled.

To resolve the issue we need to make sure that the JSX syntax is properly
configured for project, and also the jest. (Hint: Babel)

7. For JSX support, add babel presets and add .babelrc

  • Firstly Install dependancies
npm i @babel/preset-env @babel/preset-react @babel/preset-typescript --save-dev
Enter fullscreen mode Exit fullscreen mode
  • Create .babelrc file at project root, and paste following contents into it.
touch .babelrc
Enter fullscreen mode Exit fullscreen mode
//.babelrc
{
  "presets": [
    "@babel/preset-env",
    ["@babel/preset-react", { "runtime": "automatic" }],
    "@babel/preset-typescript"
  ]
}
Enter fullscreen mode Exit fullscreen mode

8. Install testing library for react

By Now previous error will be gone and you will get new error message.

node 'node_modules/.bin/jest' '/Users/satparkash/code/test-app/src
/App.test.tsx' -t 'App'
 FAIL  src/App.test.tsx
  ● Test suite failed to run

    Cannot find module '@testing-library/react' from 'src/App.test.tsx'

    > 1 | import { render } from '@testing-library/react';
        | ^
      2 | import App from './App';
      3 |
      4 | describe('App', () => {

      at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:427:11)
      at Object.require (src/App.test.tsx:1:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        0.231 s
Ran all test suites matching /\/Users\/satparkash\/code\/test-app\/src\/App.test.tsx/i with tests matching "App"

Enter fullscreen mode Exit fullscreen mode

Now, you have to add libraries which will allow you to make things happen (access VDOM, interacting …. etc), And those libraries are “@testing-library/dom”, “@testing-library/jest-dom”, “@testing-library/react” and “@testing-library/user-event”

—Mhand
npm i @testing-library/dom @testing-library/jest-dom @testing-library/react @testing-library/user-event --save-dev
Enter fullscreen mode Exit fullscreen mode

Now it's time to configure jest-environment. You will see another error message
saying Jest encountered an unexpected token, don't worry we are about to fix
it.

9. Let's Configure Jest

  • Firstly install following dependancies
npm i ts-node jest-environment-jsdom --save-dev
Enter fullscreen mode Exit fullscreen mode
  • Create a file jest.config.ts at the root project, and paste following contents into it.
touch jest.config.ts
Enter fullscreen mode Exit fullscreen mode
//jest.config.ts
export default {
  rootDir: 'src',
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
    // process `*.tsx` files with `ts-jest`
  },
  moduleNameMapper: {
    '\\.(gif|ttf|eot|svg|png)$': '<rootDir>/config/jest/fileMock.ts',
    '^.+\\.(css|less|scss|sass)$': '<rootDir>/config/jest/styleMock.ts',
  },
  setupFilesAfterEnv: ['./config/jest/setupTests.ts'],
  moduleFileExtensions: [
    // Place tsx and ts to beginning as suggestion from Jest team
    // https://jestjs.io/docs/configuration#modulefileextensions-arraystring
    'tsx',
    'ts',
    'web.js',
    'js',
    'web.ts',
    'web.tsx',
    'json',
    'web.jsx',
    'jsx',
    'node',
  ],
  modulePaths: ['<rootDir>/src'],
};
Enter fullscreen mode Exit fullscreen mode
  • Create config/jest/styleMock.ts, config/jest/fileMock.ts to mock css and files.
// config/jest/styleMock.ts

module.exports = {};
Enter fullscreen mode Exit fullscreen mode
// config/jest/fileMock.ts

export {}; //coment this if you ts-node to start complaining again
module.exports = 'test-file-stub';
Enter fullscreen mode Exit fullscreen mode
  • Create config/jest/setupTests.ts, a file that runs before each test.
//config/jest/setupTests.ts

// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';
Enter fullscreen mode Exit fullscreen mode

INFO

/**
 *
 * If imported(inside setupTests.ts):
 * import '@testing-library/jest-dom/extend-expect'
 * then we are required to map it inside `jest.config.ts` like this:
 * 

 * // jest.config.ts
 * {
 * ...,
 * moduleNameMapper: {
 * ...,
 *     '@testing-library/jest-dom/extend-expect': '@testing-library/jest-dom',
 * }
 * }
 */
Enter fullscreen mode Exit fullscreen mode

By this moment, you can run the test successfully😎.

node 'node_modules/.bin/jest' '/Users/satparkash/code/test-app/src/App.test.tsx' -t 'App'
 PASS  src/App.test.tsx
  App
    ✓ should work as expected (12 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.19 s
Ran all test suites matching /\/Users\/satparkash\/code\/test-app\/src\/App.test.tsx/i with tests matching "App".
Enter fullscreen mode Exit fullscreen mode

Happy testing 😀


10. For Snapsot Testing [optional]

For snapshot testing add react-test-renderer

npm i react-test-renderer --save-dev
Enter fullscreen mode Exit fullscreen mode

PS: I didnt' implemented snapshot testing 😄 Yet.

11. For import.meta' meta-property is only allowed when the '--module' option is... [error TS1343]

  • Error Message
error TS1343: The 'import.meta' meta-property is only allowed when the '--module' option is 'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'.

          .get(import.meta.env.VITE_API_PATH + '/api/posts')

Enter fullscreen mode Exit fullscreen mode
  • Install dependancy
npm install -D ts-jest-mock-import-meta
Enter fullscreen mode Exit fullscreen mode
  • Change the transform to mock import.meta of vite
// jest.config.ts

export default {

  ...,
    transform: {
    '^.+\\.tsx?$': [
      'ts-jest',
      {
        diagnostics: {
          ignoreCodes: [1343],
        },
        astTransformers: {
          before: [
            {
              path: 'node_modules/ts-jest-mock-import-meta',
              options: {
                metaObjectReplacement: {
                  env: {
                    // Replicate as .env.local
                    VITE_API_PATH: 'http://localhost:3001',
                  },
                },
              },
            },
          ],
        },
      },
    ],
  },
  ...
}

Enter fullscreen mode Exit fullscreen mode

References

Top comments (0)