react-native 어플리케이션에 Apollo client 통합하기 #2

Irrationnelle
Cross-Platform Korea
7 min readFeb 11, 2020

dooboolab 님께서 작성한 Integrate apollo client in react-native app #2 의 번역입니다. 피드백 환영합니다!

이전 글에서, apollo client 를 이용하여 graphql 엔드포인트를 어떻게 통합하는지 알려드렸습니다. 이번에는 이것을 이용하고 통합 테스트를 작성하는 방법에 대해 설명하겠습니다.

저희가 만든 오픈소스 채팅 어플리케이션 HackaTalk 입니다. 이번 포스팅에서는 HackaTalk 에 graphql API를 통합하는 과정을 함께 따라가보겠습니다.

그럼 SignUp 화면부터 시작하겠습니다.

위 스크린샷을 보면 저희 staging 서버와 사용 가능한 쿼리들을 확인할 수 있습니다.
어플리케이션의 SignUp 화면에 signUp mutation 쿼리를 통합합니다.

UserInput 에서 email 과 password 가 필수 매개변수인 것을 확인할 수 있습니다.

시작하겠습니다!

  1. useMutation 함수 import
import { useMutation } from '@apollo/react-hooks';

2. mutation 쿼리 생성하기

const [signUp] = useMutation<{ signUp: AuthPayload }, MutationSignUpInput>(MUTATION_SIGN_UP);

저희 프로젝트는 typescript 를 사용합니다. 그러므로 generic 으로 queries 에 타입 설정을 하여 useMutation 을 사용하겠습니다.
첫번째 제네릭 매개변수로 반환값의 타입을 설정합니다.
두번째 제네릭 매개변수로 입력(input) 변수의 타입을 설정합니다.

3. sign-up 버튼을 클릭하면, useMutation 로 만든 signUp 함수를 사용하도록 설정합니다.

버튼을 클릭하면 requestSignUp 함수를 호출하는 것을 확인할 수 있습니다.
const requestSignUp = async (): Promise<void> => {
setSigningUp(true);
const variables = {
user: {
email,
name,
password,
statusMessage,
},
}; try {
const { data } = await signUp({ variables });
AsyncStorage.setItem('token', data?.signUp.token || '');
setAuthUser(data?.signUp.user);
} catch (err) {
Alert.alert(getString('ERROR'), err.message);
} finally {
setSigningUp(false);
}
}

위 코드에서 setAuthUser 함수를 적절하게 설정했다면, 사용자가 로그인 이후 화면을 볼 수 있게 제어하는 MainStack navigation 으로 이동합니다. 이 과정은 저희가 만든 useAuthUserContext 라는 context provider 를 통해 이루어집니다.

AuthStack 과 MainStack 으로 나뉘는 삼항 연산자를 확인할 수 있습니다. 이 삼항연산자는 사용자가 로그인에 성공했을 경우 MainStack 으로 이동하도록 하고, 사용자가 로그인 하지 않았을 때에는 AuthStack 으로 이동하게 합니다.

위 코드를 보통 auth-flow 라고 하는데, 저희가 최근들어 아주 잘 사용하고 있는 react-navigation v5 로 작성한 것입니다.

성공적으로 만들었습니다! 좋군요!

4. 실제로 잘 작동하는지 확인하기 위해 playground 에서 테스트를 해봅시다.

users 에 hackatalk11@gmail.com 가 추가된 것을 확인할 수 있습니다.

5. 테스트 코드를 작성합시다!

import { MockedProvider } from '@apollo/react-testing';
  • signUp mutation 쿼리를 mocking 합니다.
const mockSignUpMutation = [
{
request: {
query: MUTATION_SIGN_UP,
variables: {
user: {
email: 'test@email.com',
name: 'name',
password: 'testpass12!',
statusMessage: 'status',
},
},
},
result: {
data: {
signUp: {
token: 'access token',
user: {
id: 'userId',
email: 'test@email.com',
nickname: 'nickname',
statusMessage: 'status',
},
},
},
},
},
];

mockSignUpMutationMockedProvider 에 전달하고, MockedProvider 로 컴포넌트를 감쌉니다.

<MockedProvider mocks={mockSignUpMutation} addTypename={false}>
<SignUp {...props} />
</MockedProvider>

여기서 알아두어야 할 점이 있습니다. 만약 native-testing-library 를 사용중이라면 굳이 waait 는 필요 없습니다. 따라서 await act(() => wait()) 로도 충분합니다. 이 부분에 대하여 강조하는 것은 Apollo 에서도 이 문서를 통해 권장하고 있는 사항이기 때문입니다.

wait() 까지 실행하면, 이제 결과를 확인할 수 있습니다!

좀 더 명시적으로 테스트를 진행하고 싶다면, 이 튜토리얼을 참고하여 진행할 수 있습니다.

지금 우리는 graphql API 를 통합할 뿐만 아니라, 이제는 개발 과정에서 당연한 절차인 테스트 코드를 작성하는 개발자가 되었습니다.

전체 소스 코드는 아래 링크에서 확인 가능합니다.

읽어주셔서 감사합니다!

--

--

Irrationnelle
Cross-Platform Korea

Avec la violence suffisante, il faut faire ta vie être l’adversité