본문으로 건너뛰기

API 통신과 token mocking

· 약 5분
arch-spatula

통신에 token이 관여할 때 취할 수 있는 전략이 있습니다. interceptor가 token 검증을 할 때 처리해볼 수 있는 문제 해결 방식입니다.

요약하면 node환경에서도 token을 저장합니다.

MSW와 axios interceptor

문제: 모의로 보내는 요청을 차단하지 않게 모의로 만들 토큰이 필요

interceptor가 토큰이 없으면 요청을 차단합니다. 하지만 모의로 보내는 요청을 차단하지 않게 모의로 만들 토큰이 필요했습니다.

const authClient: AxiosInstance = axios.create({
baseURL: BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});

axiosClient.interceptors.request.use(
(config) => {
const token = localStorage.getItem(STORAGE_KEY.ACCESS_TOKEN);

const configCopy = { ...config };
if (token) configCopy.headers.Authorization = `Bearer ${token}`;
else throw new Error('token이 없습니다.');

return configCopy;
},
(error) => Promise.reject(error)
);

클라이언트 인스턴스가 이렇게 생겼습니다.

나중에 생각난 것이지만 만약에 node 서버에서 storage접근을 차단했으면 여기서부터 에러가 발생했어야 합니다.

시도: 검색 - 로그인 mocking - 하드 코딩

검색

How to mock data response using msw and axios.create() instance

저랑 비슷한 고민을 하는 사람을 발견했습니다.

Acquiring access token crashes test.

위에 MSW에 질문한 사람도 저랑 비슷한 고민을 한 것 같습니다.

axios랑 많이 사용하는데 예시를 공식 문서에 추가하는 것도 좋아 보입니다.

로그인 mocking

describe('Card Clint', () => {
beforeAll(async () => {
await signInAPI({
email: 'username@email.com',
password: '12345678',
});
});

afterAll(() => {
localStorage.clear();
});
});

로그인 요청을 하면 응답을 받자마다 interceptor가 토큰을 저장할 것이라는 생각이 들었습니다.

하지만 더 생각해보면 그냥 직접 심으면 되겠다는 생각이 들었습니다.

해결: 테스트 환경도 그냥 localStorage.setItem

describe('Card Clint', () => {
beforeAll(() => {
localStorage.setItem(STORAGE_KEY.ACCESS_TOKEN, 'token');
});

afterAll(() => {
localStorage.clear();
});

it('should create a card', async () => {
const newCard = {
question: '',
answer: '',
submitDate: new Date(),
stackCount: 0,
};

const res = await createCardsAPI(newCard);

expect(res).toBe('1234asdf');
});
});

모의로 토큰을 심었습니다. 그러면 토큰의 존재를 확인하고 요청을 차단하지 않습니다.

이렇게 생각해보면 또 취약점입니다. 테스트 케이스로 확장해야 하는 요구사항이 생각나다니...

학습: node에서도 mocking할 때는 webStorage를 접근할 수 있습니다.

원래 beforeAll, afterAll는 node에서 실행해서 localStorage를 접근하면 에러가 발생할 것이라고 생각했습니다. 브라우저에서 제공하는 API를 node 서버환경에서는 접근이 불가능하다고 생각하고 있었습니다.

편견을 더 버릴 필요가 있습니다.

또 node 환경을 더 공부할 필요가 있습니다.

부록: 미제 사건 - nock 통신 테스트 시도

문제: nock에서 MSW로 전환 시도

규모작고 프로토타입 성격이 강한 프로젝트는 단위테스트 단위로 API mocking하는 것이 적절하다고 봤습니다. MSW처럼 백엔드 전체를 Mocking하면 코드 뿐만아니라 로직 결합도가 높아질 것이라는 생각이 들었습니다.

독립적인 단위로 쪼개두면 테스트코드를 작성할 때도 독립적이라 수월할 것이라는 생각이 들었습니다.

yarn add -D nock

설치명령을 했습니다.

vitest를 테스트 러너로 활용하고 있었습니다.

request mocking - vitest 공식 문서

MSW 이외에는 통신을 Mocking하기 어려워 보입니다.

timeout error when testing fetch with nock - vitest github issue

하지만 테스트가 정상적으로 동작하지 않았습니다.