Dev log

Integration 테스트 완벽 가이드

와이다이어리 2025. 6. 11. 22:20
반응형

Integration 테스트란?

여러 기능/컴포넌트가 함께 동작할 때의 흐름을 검증하는 테스트”

 

주요 특징

  • 여러 단위(unit)가 함께 동작하는 시나리오 테스트
  • 컴포넌트 간 데이터 흐름, 이벤트 전파 검증
  • 종종 mock 서버나 가짜 API를 사용해 전체 흐름을 시뮬레이션
  •  

전략: 어떤 흐름을 테스트할까?

🔹 폼 입력 → 버튼 클릭 → 결과 표시

// LoginForm.tsx
export function LoginForm({ onLogin }: { onLogin: (id: string) => void }) {
  const [id, setId] = useState('');
  return (
    <form onSubmit={(e) => { e.preventDefault(); onLogin(id); }}>
      <input
        placeholder="아이디"
        value={id}
        onChange={(e) => setId(e.target.value)}
      />
      <button type="submit">로그인</button>
    </form>
  );
}
// LoginForm.test.tsx
import { render, screen, fireEvent } from '@testing-library/react';
import { LoginForm } from './LoginForm';

test('아이디 입력 후 로그인 버튼을 클릭하면 onLogin 호출', () => {
  const handleLogin = jest.fn();
  render(<LoginForm onLogin={handleLogin} />);

  fireEvent.change(screen.getByPlaceholderText('아이디'), {
    target: { value: 'my-id' },
  });

  fireEvent.click(screen.getByText('로그인'));
  expect(handleLogin).toHaveBeenCalledWith('my-id');
});

 

전략: API 요청을 포함한 통합 테스트

예: 유저 데이터를 불러오는 컴포넌트

// UserInfo.tsx
export function UserInfo() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch('/api/user')
      .then((res) => res.json())
      .then(setUser);
  }, []);

  if (!user) return <p>로딩 중...</p>;
  return <p>{user.name}님 환영합니다!</p>;
}
// UserInfo.test.tsx
import { render, screen, waitFor } from '@testing-library/react';
import { UserInfo } from './UserInfo';

beforeAll(() => {
  global.fetch = vi.fn().mockResolvedValue({
    json: () => Promise.resolve({ name: '철수' }),
  });
});

test('유저 정보를 불러와서 이름을 렌더링해야 함', async () => {
  render(<UserInfo />);
  expect(screen.getByText(/로딩 중/i)).toBeInTheDocument();

  await waitFor(() =>
    expect(screen.getByText(/철수님 환영합니다/i)).toBeInTheDocument()
  );
});

 

통합 테스트는 실제 사용자 흐름을 재현하여 UI의 신뢰성을 확보하는 핵심 도구입니다.
단위 테스트가 빠르고 간결한 반면, 통합 테스트는 실제 사용 흐름을 보장합니다.

반응형