Concepts
OverviewCompositionTestingLayout
Aspect RatioBleedBoxCenterContainerDividerFlexFloatGridLink OverlayScrollableStackWrapComponents
AccordionAdmonitionAvatarButtonCarouselCheckboxComboboxConfirm ModalCTAModalDate PickerDialogFieldFieldsetFile UploaderIcon ButtonInputLoading StatesMenuNotificationsProgressPrompt ModalRadioRatingSelectSwitchTableTabsTagTextTextareaToggleTooltipUtilities
Feature FlagsForLocal StoragePortalShowsplitPropsThemeTesting
Best Practices for Testing React Components using Vitest and JestBefore writing tests, ensure your project has the necessary dependencies:
1npm install --save-dev vitest jsdom @testing-library/dom @testing-library/jest-dom @testing-library/react @testing-library/user-event
Configuration
Create the vite.config.ts
file to configure Vitest.
1import { defineConfig } from "vitest/config"2
3export default defineConfig({4 // ...5 test: {6 globals: true,7 environment: "jsdom",8 setupFiles: "./setup-test.ts",9 },10})
Setting globals: true
will automatically import the Vitest globals and removes
the need to import expect
, test
, describe
, etc.
Setup Test File
Create the setup-test.ts
file to configure the testing environment and mock
unimplemented APIs.
Here's a common example for Cerberus projects:
1import "@testing-library/jest-dom/vitest"2import { JSDOM } from "jsdom"3import ResizeObserver from "resize-observer-polyfill"4import { vi } from "vitest"5import "vitest-axe/extend-expect"6
7const { window } = new JSDOM()8
9// ResizeObserver mock10vi.stubGlobal("ResizeObserver", ResizeObserver)11window["ResizeObserver"] = ResizeObserver12
13// IntersectionObserver mock14const IntersectionObserverMock = vi.fn(() => ({15 disconnect: vi.fn(),16 observe: vi.fn(),17 takeRecords: vi.fn(),18 unobserve: vi.fn(),19}))20vi.stubGlobal("IntersectionObserver", IntersectionObserverMock)21window["IntersectionObserver"] = IntersectionObserverMock22
23// Scroll Methods mock24window.Element.prototype.scrollTo = () => {}25window.Element.prototype.scrollIntoView = () => {}26
27// requestAnimationFrame mock28window.requestAnimationFrame = (cb) => setTimeout(cb, 1000 / 60)29
30// URL object mock31window.URL.createObjectURL = () => "https://i.pravatar.cc/300"32window.URL.revokeObjectURL = () => {}33
34// navigator mock35Object.defineProperty(window, "navigator", {36 value: {37 clipboard: {38 writeText: vi.fn(),39 },40 },41})42
43// Override globalThis44Object.assign(global, { window, document: window.document })
Custom Render
First, you need to create a custom render function to wrap your component in the CerberusProvider.
1import { render as rtlRender } from "@testing-library/react"2import {3 CerberusProvider,4 defineIcons,5 makeSystemConfig,6 NotificationCenter,7} from '@cerberus/react'8
9const config = makeSystemConfig({10 icons: defineIcons({11 // Define your icons here12 // Example: "home": <svg>...</svg>13 }),14})15
16export function render(ui: ReactNode) {17 return rtlRender(<>{ui}</>, {18 wrapper: (props: PropsWithChildren) => (19 <CerberusProvider config={config}>20 {props.children}21 <NotificationCenter />22 </CerberusProvider>23 ),24 })25}
Testing Components
Now, you can use the render
function to test your components.
1import { Button } from "@cerberus/react"2import { render } from "./testing/render"3
4test("renders a button", () => {5 render(<Button>Click me</Button>)6 expect(screen.getByText("Click me")).toBeInTheDocument()7})
On this page