Testing ReactJS Applications with Vitest in Typescript

I am going to assume your project has been built on vite. I will be installing my dependencies using pnpm but you can use npm or any manager you want it.

Setting up Vitest

In order to use describe, test, and expect as in jest we will install vitest as development dependency

pnpm add -D vitest

Now in our vite.config.js file we will add the next line

/// <reference types="vitest" />
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
 
export default defineConfig({
  plugins: [react()],
})

and in our package.json we add the next script

{
  "name": "reactjs-testing-in-typescript-base",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview",
    "test": "vitest"
  },
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.66",
    "@types/react-dom": "^18.2.22",
    "@typescript-eslint/eslint-plugin": "^7.2.0",
    "@typescript-eslint/parser": "^7.2.0",
    "@vitejs/plugin-react": "^4.2.1",
    "eslint": "^8.57.0",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.6",
    "typescript": "^5.2.2",
    "vite": "^5.2.0",
    "vitest": "^1.6.0"
  }
}

Now for adding test files we just have to name them either Component.test.tsx or Component.spec.tsx. Component will be the name of your component. For instance we will create the next simple test file:

App.test.tsx

import {describe, test, expect} from 'vitest'
 
describe('<App />', ()=> {
  test('simple test', ()=>{
    expect(10).toBe(10);
  })
})

And now we run our in our terminal test script

pnpm test

We will get something like this:

tests

if we want a visual view instead of the terminal we can add the next script :

"scripts": {
  "dev": "vite",
  "build": "tsc && vite build",
  "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
  "preview": "vite preview",
  "test": "vitest",
  "test:ui": "vitest --ui"
},

and install the next dependency

pnpm add -D @vitest/ui

Now you can run the script

pnpm test:ui

and you will see the next screen in your browser

tests

At this point we can create unit testing, but we can not test ReactJS Components so we are going to install @testing-library/react and happy-dom. The happy-dom library is for having a browser (without its graphical user interface) for NodeJS.

pnpm add -D @testing-library/react happy-dom

Now we need to configure them. In our vite.config.js file we will add the next lines

/// <reference types="vitest" />
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react"
 
export default defineConfig({
  plugins: [react()],
  test: {
    environment: "happy-dom"
  },
})

Take this for example: App.test.tsx, to check if App.tsx is displaying ReactJS Application text

import {describe, test, expect} from 'vitest'
import {render} from '@testing-library/react'
import App from './App';
 
describe('<App />', ()=> {
  test('renders title', ()=>{
    const {getByText} = render(<App />)
    const title = getByText("ReactJS Application")
    expect(title).not.toBe(undefined);
  })
})

To extend the matchers of vitest you can install the next dependency:

pnpm add -D @testing-library/jest-dom

Now we can check if the text is placed in the document using the custom matchers:

import {describe, test, expect} from 'vitest'
import {render} from '@testing-library/react'
import '@testing-library/jest-dom/vitest'
 
import App from './App'
 
describe('<App />', ()=> {
  test('renders title', ()=>{
    const {getByText} = render(<App />)
    const title = getByText("ReactJS Application")
    expect(title).toBeInTheDocument()
  })
})

Finally we can install the next dependencies for testing hooks and user events

pnpm add -D @testing-library/user-event @testing-library/react-hooks

In my next post I will show you how to test Components whose have interactions with APIs

Happy Hacking!