import React from 'react';import { render, screen } from '@testing-library/react';import userEvent from '@testing-library/user-event'; // 사용자 이벤트 시뮬레이션import Button from './Button';test('버튼 클릭 시 onClick 핸들러가 호출된다', async () => { const handleClick = jest.fn(); // jest.fn()으로 모의(mock) 함수 생성 render(<Button onClick={handleClick}>클릭하세요</Button>); const buttonElement = screen.getByRole('button', { name: '클릭하세요' }); // 사용자 이벤트 시뮬레이션 (실제 클릭과 더 유사) await userEvent.click(buttonElement); // handleClick 함수가 1번 호출되었는지 확인 expect(handleClick).toHaveBeenCalledTimes(1);});
import React from 'react';import { render, screen, waitFor } from '@testing-library/react';import userEvent from '@testing-library/user-event';import axios from 'axios'; // API 호출 라이브러리import UserProfileLoader from './UserProfileLoader';// axios.get 함수를 모킹jest.mock('axios');const mockedAxios = axios as jest.Mocked<typeof axios>;test('사용자 데이터 로드 후 프로필 정보 표시', async () => { // API 성공 응답 모킹 const mockUserData = { name: 'Alice', email: 'alice@example.com' }; mockedAxios.get.mockResolvedValue({ data: mockUserData }); render(<UserProfileLoader userId="1" />); // 초기 로딩 상태 확인 (선택적) expect(screen.getByText(/로딩 중/i)).toBeInTheDocument(); // API 호출 후 데이터가 화면에 표시될 때까지 기다림 // findBy* 쿼리는 요소가 나타날 때까지 자동으로 기다림 (기본 타임아웃 1000ms) const userNameElement = await screen.findByText(mockUserData.name); expect(userNameElement).toBeInTheDocument(); // waitFor: 특정 조건이 만족될 때까지 기다림 (find* 로 충분하지 않을 때 사용) // await waitFor(() => { // expect(screen.getByText(mockUserData.email)).toBeInTheDocument(); // }); // 로딩 메시지가 사라졌는지 확인 expect(screen.queryByText(/로딩 중/i)).not.toBeInTheDocument();});test('API 호출 실패 시 에러 메시지 표시', async () => { // API 실패 응답 모킹 const errorMessage = '데이터를 불러올 수 없습니다.'; mockedAxios.get.mockRejectedValue(new Error(errorMessage)); render(<UserProfileLoader userId="1" />); // 에러 메시지가 화면에 표시될 때까지 기다림 const errorElement = await screen.findByText(new RegExp(errorMessage, 'i')); expect(errorElement).toBeInTheDocument();});
import React from 'react';import type { Meta, StoryObj } from '@storybook/react';import Button from './Button'; // 실제 컴포넌트// 메타 정보: 컴포넌트 설명서 표지 같은 거예요const meta: Meta<typeof Button> = { title: 'Components/Button', // 어디에 둘지 정해요 component: Button, // 주인공 컴포넌트 tags: ['autodocs'], // 자동으로 설명서 만들기 argTypes: { /* ... props 조종판 설정 ... */ },};export default meta;type Story = StoryObj<typeof Button>;// 첫 번째 이야기: 기본 모습 버튼export const Primary: Story = { args: { primary: true, label: 'Button' }, // 이렇게 생겼어요 하고 알려줘요};// 두 번째 이야기: 보조 역할 버튼export const Secondary: Story = { args: { label: 'Button' },};// ... 더 많은 이야기들 ...