Testing
Testing
Vitest와 Jest를 사용해 React 컴포넌트를 테스트하는 모범 사례를 다루는 개념 문서예요.
출처: 문서
본문
Vitest 또는 Jest로 테스트를 작성할 때는 다음 관행을 사용해 최상의 결과를 얻어 보세요.
:::note
일반적으로 Jest보다 Vitest를 권장하지만, 설정은 비슷해요.
:::
설정 (Setup)
테스트를 작성하기 전에 프로젝트에 필요한 의존성이 있는지 확인해 주세요:
npm install --save-dev vitest jsdom @testing-library/dom @testing-library/jest-dom @testing-library/react @testing-library/user-event
구성 (Configuration)
Vitest를 구성하려면 vite.config.ts 파일을 만들어 주세요.
import { defineConfig } from "vitest/config"
export default defineConfig({
// ...
test: {
globals: true,
environment: "jsdom",
setupFiles: "./setup-test.ts",
},
})
globals: true로 설정하면 Vitest globals가 자동으로 import되어 expect, test, describe 등을 별도로 import할 필요가 없어져요.
테스트 파일 설정 (Setup Test File)
테스트 환경을 구성하고 미구현 API를 mock하려면 setup-test.ts 파일을 만들어 주세요.
다음은 Chakra v3 프로젝트의 일반적인 예시예요:
import "@testing-library/jest-dom/vitest"
import { JSDOM } from "jsdom"
import ResizeObserver from "resize-observer-polyfill"
import { vi } from "vitest"
import "vitest-axe/extend-expect"
const { window } = new JSDOM()
// ResizeObserver mock
vi.stubGlobal("ResizeObserver", ResizeObserver)
window["ResizeObserver"] = ResizeObserver
// matchMedia mock
Object.defineProperty(window, "matchMedia", {
writable: true,
value: vi.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: vi.fn(), // deprecated
removeListener: vi.fn(), // deprecated
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
dispatchEvent: vi.fn(),
})),
})
// IntersectionObserver mock
const IntersectionObserverMock = vi.fn(() => ({
disconnect: vi.fn(),
observe: vi.fn(),
takeRecords: vi.fn(),
unobserve: vi.fn(),
}))
vi.stubGlobal("IntersectionObserver", IntersectionObserverMock)
window["IntersectionObserver"] = IntersectionObserverMock
// Scroll Methods mock
window.Element.prototype.scrollTo = () => {}
window.Element.prototype.scrollIntoView = () => {}
// requestAnimationFrame mock
window.requestAnimationFrame = (cb) => setTimeout(cb, 1000 / 60)
// URL object mock
window.URL.createObjectURL = () => "https://i.pravatar.cc/300"
window.URL.revokeObjectURL = () => {}
// navigator mock
Object.defineProperty(window, "navigator", {
value: {
clipboard: {
writeText: vi.fn(),
},
},
})
// Override globalThis
Object.assign(global, { window, document: window.document })
커스텀 렌더 (Custom Render)
먼저, 컴포넌트를 ChakraProvider로 감싸는 커스텀 렌더 함수를 만들어야 해요.
// ./testing/render.tsx
import { Provider } from "@/components/ui/provider"
import { render as rtlRender } from "@testing-library/react"
export function render(ui: React.ReactNode) {
return rtlRender(<>{ui}</>, {
wrapper: (props: React.PropsWithChildren) => (
<Provider>{props.children}</Provider>
),
})
}
컴포넌트 테스트 (Testing Components)
이제 render 함수를 사용해 컴포넌트를 테스트할 수 있어요.
import { Button } from "@chakra-ui/react"
import { render } from "./testing/render"
test("renders a button", () => {
render(<Button>Click me</Button>)
expect(screen.getByText("Click me")).toBeInTheDocument()
})
더 알아보기 (Learn more)
Chakra UI 컴포넌트를 테스트하는 더 자세한 내용은 공식 문서를 확인해 보세요.