[ApolloClient] MockedProvider사용하기
지난 시간에 이어서 이번엔 mock-apollo-client 라이브러리를 사용해서 Mocking을 해보려 한다.
ApolloClient에서 제공하는 MockedProvider는 배열에 Query,input,outpu모든 값들을 나열해야하는 데 이 방식은 사용성이 좋지 않다고 판단해서 추가적인 서칭을 진행했다.
mock-apollo-client 라이브러리는 배열에 값을 넣는 방식이 아닌 handler에 1대1로 매핑해서 사용하는 방식으로 더 편리해보여서 선택했다.
mock-apollo-client를 개발한 사람의 설명을 읽어보니 apolloClient의 MockedProvider를 사용하다가 한계를 느껴서 직접 개발했다고 한다.
직면한 문제는 아래와 같다고 한다.
1. 예상한 변수로 쿼리/뮤테이션이 호출되었는지 확인할 수 없음
2. 특정 쿼리가 호출된 횟수를 확인할 수 없음
3. MockedProvider 초기화 후 쿼리/뮤테이션 결과를 변경할 수 없음
4. 쿼리/뮤테이션 로딩 상태를 쉽게 제어할 수 없음
기본적은 사용법은 아래와 같다.
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"}
},
});
}
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>
}
개인적으론 MockedProvider보다는 handler에 쿼리에 대한 응답값을 조건에 맞춰서 다르게 지정할 수 있도록 하는 부분과 input값 그대로 output으로 리턴할 수 있는 부분들이 사용성이 좋게 느껴졌다.
이대로 mock-apollo-client를 선택하려고 했는데 이번엔 MSW라는 더 많은 사람들이 사용하는 라이브러리를 알게 되었다. 이야... 이렇게 된거 MSW까지 다뤄보고 선택해보려 한다.
(만약 위 단점을 해소 할수 있다면 나는 MSW를 선택하고 싶다)