Skip to main content
Version: v9

Unit Testing Setup

Ionic requires a few additional steps to set up unit tests. If you are using an Ionic starter project, Vitest, React Testing Library, and jest-dom are already installed and src/setupTests.ts is already configured; you only need to initialize Ionic React as described below.

Install Vitest​

Vitest runs the tests. It uses jsdom to provide a browser-like environment for the components.

npm install --save-dev vitest jsdom

Then configure Vitest in vite.config.ts to use jsdom and load src/setupTests.ts before the tests run:

vite.config.ts
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vitest/config';

export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
setupFiles: './src/setupTests.ts',
include: ['src/**/*.test.{ts,tsx}'],
},
});

Install React Testing Library​

React Testing Library is a set of utilities that make it easier to test React components. It's used to interact with components and test their behavior.

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

To simulate user interactions with user-event, install it as well. It is not included in Ionic starter projects:

npm install --save-dev @testing-library/user-event

Initialize Ionic React​

Ionic React requires the setupIonicReact function to be called before any tests are run. Failing to do so will result in mode-based classes and platform behaviors not being applied to your components.

In src/setupTests.ts, add the following code:

// Adds jest-dom's DOM matchers (toBeInTheDocument, toHaveTextContent, ...) to Vitest's expect.
import '@testing-library/jest-dom/vitest';
+ import { setupIonicReact } from '@ionic/react';
import { cleanup } from '@testing-library/react';
import { afterEach } from 'vitest';

+ setupIonicReact();
+
// Testing Library only cleans up automatically when Vitest globals are enabled.
afterEach(() => {
cleanup();
});

// jsdom doesn't implement matchMedia, which Ionic uses for platform and dark mode checks.
window.matchMedia =
window.matchMedia ||
function (query: string): MediaQueryList {
return {
matches: false,
media: query,
onchange: null,
addListener: () => undefined,
removeListener: () => undefined,
addEventListener: () => undefined,
removeEventListener: () => undefined,
dispatchEvent: () => false,
};
};