React Setting up Vite with Jest

From bibbleWiki
Jump to navigation Jump to search

Introduction

This is a page to help set up vite with jest which did not work out of the box

Steps

Setup Project

Create project

npm init vite@latest demo-project -- --template react-ts

Add Node Engine

{
  "name": "demo-project",
  "version": "0.0.0",
  "engines":{
    "node": ">=16.13.0",
    "npm": ">=8.1.0"
  },
  // ...
}

Setup VS Code

In .vscode/setting.json add

{
    "jest.jestCommandLine": "/usr/bin/jest",
}

Install and test Jest

Install Jest

npm install jest --save-dev

Add to packages Test

  "scripts":{
    // ...
    "test": "jest"
  },

Add a dummy test in __test__/demo.test.js. Note the js

test('demo', () => {
  expect(true).toBe(true)
})

Running the test should work

npm run test

Setup Typescript

Next lets use typescript

npm install ts-jest @types/jest --save-dev

And tell jest to use typescript in jest.config.cjs

module.exports = {
  preset: 'ts-jest',
}

Note the cjs and not js. This is quite important and will produce the error

ReferenceError: module is not defined in ES module scope
This file is being treated as an ES module because it has a '.js' file extension and '/home/iwiseman/dev/projects/vite_bunler/demo-project/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
    at file:///home/iwiseman/dev/projects/vite_bunler/demo-project/jest.config.js:1:1
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

Add other Testing libraries

Now lets add react testing library

npm install @testing-library/react @testing-library/jest-dom --save-dev

Install jest-environment-jsdom as it no longer shipped by default

npm i jest-environment-jsdom -D

Add it to the jest.config.cjs so it now looks like this

module.exports = {
  preset: 'ts-jest',
  testEnvironment: "jest-environment-jsdom",
}

Now add a test case App.test.tsx

import '@testing-library/jest-dom'
import { render, screen } from '@testing-library/react'
import App from '../App'

it('renders hello message', () => {
  render(<App />)
  expect(screen.getByText('Vite + React')).toBeInTheDocument()
})

We now run the test with npm test and it fails with

   SyntaxError: Unexpected token '<'

      1 | import { useState } from 'react'
    > 2 | import reactLogo from './assets/react.svg'
        | ^
      3 | import viteLogo from '/vite.svg'
      4 | import './App.css'
      5 |

      at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1505:14)
      at Object.<anonymous> (src/App.tsx:2:1)
      at Object.<anonymous> (src/__test__/app.test.tsx:3:1)

This is because importing of svg and other image files does not work. To fix this we need to install and config identity-obj-proxy

identity-obj-proxy

To use this we need to install it and config a mock for it

  • Install
  • Config Mock
  • Config Jest

Install

Eezy Peezy

npm install identity-obj-proxy --save-dev

Config Mock

Make a __mock__ directory in the root of the project not src and create a file in __mock__/fileMock.cjs

module.exports = 'test-file-stub'

Config Jest

Now need to configure jest.test.cjs for this to work

module.exports = {
  preset: 'ts-jest',
  testEnvironment: "jest-environment-jsdom",
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
      '<rootDir>/__mocks__/fileMock.cjs',
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
  },

}

Now npm run test should work