mock-apollo-client 사용하기

WooJu·2024년 8월 13일

개발

목록 보기
5/12

[ApolloClient] MockedProvider사용하기

지난 시간에 이어서 이번엔 mock-apollo-client 라이브러리를 사용해서 Mocking을 해보려 한다.

배경


ApolloClient에서 제공하는 MockedProvider는 배열에 Query,input,outpu모든 값들을 나열해야하는 데 이 방식은 사용성이 좋지 않다고 판단해서 추가적인 서칭을 진행했다.
mock-apollo-client 라이브러리는 배열에 값을 넣는 방식이 아닌 handler에 1대1로 매핑해서 사용하는 방식으로 더 편리해보여서 선택했다.

mock-apollo-client


mock-apollo-client를 개발한 사람의 설명을 읽어보니 apolloClient의 MockedProvider를 사용하다가 한계를 느껴서 직접 개발했다고 한다.

직면한 문제는 아래와 같다고 한다.
1. 예상한 변수로 쿼리/뮤테이션이 호출되었는지 확인할 수 없음
2. 특정 쿼리가 호출된 횟수를 확인할 수 없음
3. MockedProvider 초기화 후 쿼리/뮤테이션 결과를 변경할 수 없음
4. 쿼리/뮤테이션 로딩 상태를 쉽게 제어할 수 없음

mock-apollo-client github

사용법


기본적은 사용법은 아래와 같다.

import {createMockClient} from "mock-apollo-client"

// 쿼리 정의
const GET_USER = gql`
  query GetUser($id: ID!) {
    user(id: $id) {
      id
      name
    }
  }
`;


// 모의 클라이언트 생성
const mockClient = createMockClient();

// 모의 응답 설정
mockClient.setRequestHandler(GET_USER, (req) =>
  Promise.resolve({ data: { user: { id: req.id, name: "John Doe" } } }),
);

const TestPage=()=>{
  const { refetch } = useQuery(GET_USER, {
    client: mockClient,
    variables:{id:10},
    onCompleted: data => {
      console.log("get user >>> ", data); // {id:10, name: "John Doe"}
    },
  });
}
  1. createMockClient()로 모의 클라이언트 객체를 생성한 후
  2. setRequestHandler()로 특정 쿼리에 응답값을 지정해 둔다
  3. useQuery에서 동일한 쿼리를 실제로 요청하면 미리 지정해둔 응답값이 리턴된다.

input에 따라 응답값을 데이터 혹은 Error를 리턴하도록 제어할 수 있다.

// 모의 클라이언트 생성
const mockClient = createMockClient();

// 모의 응답 설정
mockClient.setRequestHandler(GET_USER, req => {
  const { id } = req;
  if (id < 10) {
    return Promise.resolve({ data: { user: { id: id, name: "John Doe" } } });
  } else {
    return Promise.reject(new Error("too many id"));
  }
});

Query뿐만 아니라 Mutation도 사용가능하다

import {createMockClient} from "mock-apollo-client"

const CREATE_USER = gql`
  mutation CreateUser($name: String!) {
    createUser(name: $name) {
      id
      name
    }
  }
`;

mockClient.setRequestHandler(CREATE_USER, req => {
  const { id, name } = req;
  if (id) {
    return Promise.resolve({ data: { createUser: { id, name } } });
  } else {
    return Promise.reject(new Error("There is no Id"));
  }
});

const ManagementPage=()=>{
  const [mutate] = useMutation(CREATE_USER, {
    client: mockClient,
    onCompleted: data => {
      console.log("create user >>> ", data);
    },
  });
  
return <button onClick={async () =>
          await mutate({
            variables: {
              id: 1,
              name: "jang",
            },
          })
        }
      >
        mutate
      </button>
}

마무리


장점

  • setRequestHandler내부에서 input,output을 1대1로 매칭하여 사용성이 좋음

단점

  • 모킹 할 쿼리문에 mockClient()를 별도로 생성해서 Query문안에 client에 일일이 넣어야함 (+ 실제 백엔드 쿼리를 연결할땐 일일이 지워야 한다)

개인적으론 MockedProvider보다는 handler에 쿼리에 대한 응답값을 조건에 맞춰서 다르게 지정할 수 있도록 하는 부분과 input값 그대로 output으로 리턴할 수 있는 부분들이 사용성이 좋게 느껴졌다.
이대로 mock-apollo-client를 선택하려고 했는데 이번엔 MSW라는 더 많은 사람들이 사용하는 라이브러리를 알게 되었다. 이야... 이렇게 된거 MSW까지 다뤄보고 선택해보려 한다.
(만약 위 단점을 해소 할수 있다면 나는 MSW를 선택하고 싶다)

profile
모르는게 너무 많아

0개의 댓글