목차
브라우저에서 API를 콜할 때 xhr객체를 이용해서 API를 호출합니다.
그런데 리액트에서 사용하는 테스팅 환경은 Node.js 기반입니다.
그러면 xhr객체를 지원하지 않을텐데, 과연 호출이 될까 궁금했습니다.
결론부터 말하면 일단 호출이 안되었습니다. 어떻게 확인을 했는 지 궁금하시면 아래를 읽어주세요.수정) 호출이 됩니다! 제가 useEffect 내부에서 호출을 해서 호출이 안되는 것처럼 느껴졌는데, 호출이 되네요. 잘못된 정보 전달 죄송합니다.
테스트 환경에서 API가 호출 되는 것이 좋을까? 안좋을까?
우선 호출이 되는 것이 좋을 지, 안좋을 지에 대해서 생각해보았습니다.
UI를 구성할 때 클라이언트 상태를 이용할 수 있지만, 서버에서 받아와서 뿌려주는 경우가 대다수입니다.
그런데 프론트엔드에서 테스트를 할 때 UI가 잘 그려졌는지 안 그려졌는지 알아보려고 서버에서 받아온 값에 의존하게 되면 그 테스트는 서버의 상태에 따라서 성공할 수 있고, 실패할 수도 있습니다.
그렇기 때문에 서버 상태와는 독립적으로 테스트가 실행이 되는 것이 좋다고 판단됩니다.
API 호출이 되는 지 알아보자
API 호출이 되는 것을 알아보기 위해서 프로젝트를 CRA로 만들어서 작업을 했습니다. 우선 Fetch라는 컴포넌트를 만들었습니다.
// Fetch.tsx
import { useEffect } from "react";
export function Fetch(): JSX.Element {
useEffect(() => {
const xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:3002/list");
xhr.onreadystatechange = function (event: any) {
if (event.target) {
if (event.target.readyState === XMLHttpRequest.DONE) {
const { status } = event.target;
if (status === 0 || (status >= 200 && status < 400)) {
console.log(JSON.parse(xhr.response));
// 요청이 정상적으로 처리 된 경우
} else {
// 에러가 발생한 경우
}
}
}
};
xhr.send();
});
return (
<div className="Fetch">
<ul>
<li>아이템1</li>
<li>아이템2</li>
</ul>
</div>
);
}
위에 처럼 코드를 짜서 렌더가 되면 요청이 가도록 만들었습니다.
또한 서버에게 요청이 가는 지 알아내기 위해서 express.js를 이용해서 간단하게 서버를 구현했습니다.
// app.js
const express = require('express');
const cors = require('cors');
const app = express();
const PORT = 3002;
app.use(cors());
app.get('/list', (req, res) => {
log('리스트 요청'); // 서버에 요청이 들어오면 로그를 찍도록 했다.
res.json({results: [{id: 0, value: 'HELLO', id: 1, value: 'WORLD!'}]});
});
app.listen(PORT, () => {
console.log(`Server Litsen at ${PORT}`);
})
function log(params) {
console.log(params);
}
그리고 브라우저를 열어서 서버에 로그가 찍히는 지 확인 해보았습니다.
![](https://blog.kakaocdn.net/dn/sCiGR/btrGt3CkG23/45LkXE2AZY6spSAK1booyk/img.png)
![](https://blog.kakaocdn.net/dn/bGejNf/btrGlUNbEhL/pkzgPkGAyCdTB8kBNwryek/img.png)
![](https://blog.kakaocdn.net/dn/yOF6D/btrGu3hgLqP/tRhEc2NlEQ4wbPRuFmfwsk/img.png)
당연히 요청이 가게 되었고, 서버에는 로그가 찍혔습니다.
그러면 테스트를 이용해서 해당 컴포넌트를 렌더한다면 어떻게 되었을까요??
아래 테스트 코드를 보면 렌더를 하고 스크린 상에 렌더가 잘 되었는지 확인하는 코드입니다.
// Fetch.test.tsx
import { render, screen } from "@testing-library/react";
import { Fetch } from "./Fetch";
describe("Fetch 컴포넌트 렌더 테스트", () => {
it("서버가 호출이 될까??", () => {
render(<Fetch />);
expect(screen.getByText("아이템1")).toBeInTheDocument();
});
});
npm test 명령어를 통해서 테스트를 실행시켰습니다.
![](https://blog.kakaocdn.net/dn/XxOsu/btrGtPEl0js/knlmPR24wP7pmQhwHE9fQ1/img.png)
![](https://blog.kakaocdn.net/dn/cAh4v3/btrGtghWbft/VaRFuCxgtVOHq1R3HKZyDk/img.png)
![](https://blog.kakaocdn.net/dn/dnV8sD/btrGtOSZD8l/w8ir2HYBOvh1O3kLATeKgK/img.png)
서버에 요청이 들어오지 않았습니다.
그러면 위에서 언급한 서버 상태에 의존하지 않고 개발을 하기 위해서는 어떤 방법을 이용해야 할까?
자료를 찾아보니 mocking을 해야한다고 한다. 이것은 공부해서 다음에 올리도록 하겠습니다.
'테스트' 카테고리의 다른 글
프론트엔드에서 TDD가 가능할까? (개인적인 생각 및 고충) (1) | 2023.01.06 |
---|