코드도보통지

5관문. Dependency Injection

관문 5 / 7

Context를 통해 API 서비스를 주입하여 테스트 시 Mock 서비스로 교체 가능하도록 만들어라.

📖 이론 비급

Dependency Injection via Context

하드코딩된 서비스 의존성은 테스트와 교체를 어렵게 만든다. Context를 통해 인터페이스에 의존하면 구현을 외부에서 주입할 수 있다.

<ApiContext.Provider value={mockApi}>로 테스트 환경에서 mock을 주입하고 <ApiContext.Provider value={realApi}>로 프로덕션에서 실제 서비스를 사용한다. 컴포넌트는 구현을 알 필요 없이 인터페이스만 호출한다.

⚔️ 수련 코드

import { createContext, useContext, useState } from 'react';

// API 인터페이스 정의
const realApi = {
  fetchUsers: () => fetch('https://jsonplaceholder.typicode.com/users').then(r => r.json()),
};

const mockApi = {
  fetchUsers: () => Promise.resolve([{ id: 1, name: 'Mock User' }]),
};

// TODO: ApiContext를 생성하고 useApi 훅을 만들어라
const ApiContext = createContext(null);
export const useApi = () => useContext(ApiContext);

function UserList() {
  const api = useApi();
  const [users, setUsers] = useState([]);
  // TODO: api.fetchUsers()를 호출하여 users를 채워라
  return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>;
}

export default function App() {
  const useMock = true; // 테스트 시 true, 프로덕션 시 false
  return (
    <ApiContext.Provider value={useMock ? mockApi : realApi}>
      <UserList />
    </ApiContext.Provider>
  );
}