๐ŸŽ„ ์„ฑ์žฅ์ผ์ง€ 4.0

์ฑ… ํ–‰๋ณตํ•œ ์ด๊ธฐ์ฃผ์˜์ž(์›จ์ธ ๋‹ค์ด์–ด)์˜ ๋‚ด์šฉ์— ์ž๊ทน๋ฐ›์•„ ์‹œ์ž‘ํ•˜๋Š” ์†Œ๋ฐ•ํ•œ ์„ฑ์žฅ๊ธฐ๋ก

์‚ด์•„์žˆ๋Š” ๊ฝƒ๊ณผ ์ฃฝ์€ ๊ฝƒ์€ ์–ด๋–ป๊ฒŒ ๊ตฌ๋ณ„ํ•˜๋Š”๊ฐ€?
์„ฑ์žฅํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด ์‚ด์•„ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.
์ƒ๋ช…์˜ ์œ ์ผํ•œ ์ฆ๊ฑฐ๋Š” ์„ฑ์žฅ์ด๋‹ค!

๐ŸŒณ (1.0)ํ‚ค์›Œ๋“œ
์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ •๋ฆฌ, ์ถ”ํ›„์— ๋ณด๋ฉด์„œ ์Šค์Šค๋กœ ์„ค๋ช…
๐Ÿ‰ (2.0)๊ฒฝํ—˜ ์œ„์ฃผ๋กœ
๋‹จ์ˆœ ์ •๋ณด๋ฅผ ์ „๋‹ฌํ•˜๊ธฐ๋ณด๋‹ค ๋ฌด์—‡์„ ๋ฐฐ์› ๊ณ  ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ–ˆ๋Š”์ง€ ์งง๊ณ  ๊ฐ„๋‹จํ•˜๊ฒŒ ์ž‘์„ฑ
โ„๏ธ (3.0)์ •ํ•ด์ง„ ํ…œํ”Œ๋ฆฟ์— ๋งž์ถฐ์„œ
ํ‚ค์›Œ๋“œ, ๊ฒฝํ—˜ ๋ชจ๋‘ ์ข‹๋‹ค. ๋‹ค๋งŒ ๋งค์ผ ์ž‘์„ฑํ•˜๊ธฐ๋กœ ๋งˆ์Œ ๋จน์€๋งŒํผ ํ•ต์‹ฌ๋งŒ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ…œํ”Œ๋ฆฟ์„ ์ž‘์„ฑ
(3.1)230102๋ถ€ํ„ฐ ์‹œ์ž‘๋˜๋Š” ํ•™์Šต์— ๊ด€ํ•œ ๋‚ด์šฉ ์ถ”๊ฐ€
(3.2)230313๋ถ€ํ„ฐ ์ข€๋” ๊ฒฝํ—˜, ๊ฐ์ • ์œ„์ฃผ์˜ ๋‚ด์šฉ๋„ ๋‹ด๊ธฐ!
๐ŸŒพ (4.0)ํ•™์Šต ํ‚ค์›Œ๋“œ์—์„œ ์ตœ๋Œ€ํ•œ ๊ฐ„๋‹จํ•œ ์ •๋ณด ์ œ๊ณต, ๊ณ ๋ฏผ์—์„œ ๋‚ด ๊ฒฝํ—˜์„ ์ž์„ธํžˆ ์ ์ž!

๐Ÿง ๊ณ ๋ฏผ ์‚ฌํ•ญ

1. [์ปดํฌ๋„ŒํŠธ ๋ฆฌํŒฉํ† ๋ง] ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ์— element๋กœ attach ํ›„ setState ํ–ˆ์„ ๋•Œ, ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ๋ฐ˜์˜๋˜๊ฒŒ ์–ด๋–ป๊ฒŒ ํ•˜์ง€..?

์ผ๋‹จ ๋ฆฌํŒฉํ† ๋ง์„ ํ†ตํ•ด์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋“ค์˜ constructor์—์„œ setState๋ฅผ ํ†ตํ•ด ํ™”๋ฉด์„ ๋ฐ”๊พธ๋Š” ๊ฒƒ๊นŒ์ง€๋Š” ์„ฑ๊ณตํ–ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋ฌธ์ œ๋Š” ๋ถ€๋ชจ์ปดํฌ๋„ŒํŠธ์—์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ™์ด๊ณ  ๋‚˜์„œ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ์˜ element๊ฐ€ ๋ฐ”๋€Œ์—ˆ์„ ๋•Œ..! ์ด ๋•Œ ๋ณ€๊ฒฝ์‚ฌํ•ญ์ด ๋ฐ˜์˜์ด ๋˜์–ด์•ผํ•˜๋Š”๋ฐโ€ฆ constructor์—์„œ setState ๋˜๋Š” ๊ฒƒ์™ธ์— setTimeout์ด๋‚˜ setInterval์„ ํ†ตํ•ด ๋‚˜์ค‘์— ๋ณ€๊ฒฝ๋˜์—ˆ์„ ๋•Œ๋Š” ๋‹น์—ฐํžˆ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ด๋ฏธ attachTo ํ–ˆ์„ ๋•Œ ๋ถ™์€ element์™€ ๋‚˜์ค‘์— ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ƒ์„ฑํ•œ element๊ฐ€ ๋‹ค๋ฅธ element์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. attach ํ•˜๋Š” ๋ถ€๋ถ„์„ innerHTML๊ณผ outerHTML์„ ์ด์šฉํ•ด์„œ ์–ด๋–ป๊ฒŒ ํ•˜๋ฉด ๋  ๊ฑฐ ๊ฐ™์€๋ฐโ€ฆ ํ์–ด ์ง„์งœ ์ด ๋ถ€๋ถ„๋•Œ๋ฌธ์— ๋„ˆ๋ฌด ํž˜๋“ค๋‹คใ…  ๊ทธ๋ž˜๋„ ์ฐจ๊ทผ์ฐจ๊ทผ ๋ฆฌํŒฉํ† ๋งํ•ด๋ณด์ž!!!

2. [ํ…Œ์ŠคํŠธ ์ฝ”๋“œ] ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๋Š” ๋กœ์ง์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ ์‹œ, server์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ์—†์•จ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์„๊นŒ?

์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋„, fetch๋ฅผ ํ†ตํ•ด ์„œ๋ฒ„์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„ ๊ทธ ๊ฐ’์„ ํ…Œ์ŠคํŠธํ•˜๊ฒŒ ๋œ๋‹ค. ํ—Œ๋ฐ ๋งŒ์•ฝ์— ์„œ๋ฒ„๊ฐ€ ๊บผ์ง„๋‹ค๋ฉด..? ์„œ๋ฒ„๊ฐ€ ๋‹น์žฅ ์—†๋‹ค๋ฉด..? ์ด๋Ÿด ๋•Œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ์ž‘์„ฑํ•˜๊ณ  ์‹คํ–‰ํ•ด๋ณผ ์ˆ˜ ์žˆ์„๊นŒ? ์ผ๋‹จ ์•Œ์•„๋ณธ ๋ฐ”๋กœ๋Š” mock server๋ผ๋Š” ๊ฐ€์งœ ์„œ๋ฒ„๋ฅผ ๋งŒ๋“ค์–ด์„œ ํ…Œ์ŠคํŠธํ•ด๋ณด๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋„ ์•Œ์•„๋ด์•ผ๊ฒ ๋‹ค..! (์˜ˆ์ „์— ์จ๋ณด๋ ค๋‹ค๊ฐ€ ๋ฒˆ๋“ค๋Ÿฌ ์—†์ด๋Š” ์•ˆ๋˜์—ˆ๋˜ MSW์™€ ๊นŠ์€ ์—ฐ๊ด€์ด ์žˆ๋Š”๋“ฏ!!)

๐Ÿ”‘ ์˜ค๋Š˜์˜ ํ•™์Šต ํ‚ค์›Œ๋“œ

  • ๋ฆฌํŒฉํ† ๋ง๊ณผ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ

๐Ÿฅณ ํ•™์Šต ๋‚ด์šฉ

๋ฆฌํŒฉํ† ๋ง์„ ์œ„ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์ž‘์„ฑ(feat. Jest)

๊ธฐ์กด์˜ MVC, Observer pattern์—์„œ Flux pattern์œผ๋กœ ๋ฆฌํŒฉํ† ๋งํ•˜๊ธฐ์— ์•ž์„œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ถ€ํ„ฐ ์ž‘์„ฑํ•˜๊ณ  ์—ฐ์Šตํ•ด๋ณด์•˜๋‹ค.(๊ณ ๋‚œ๊ธธ ๊ฐ€๊ธฐ ์ „ ๊ทธ๋‚˜๋งˆ ์‹ฌ์  ๋Œ€๋น„ใ… ใ…‹ใ…‹)

์˜ˆ์‹œ3) fetch์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ ๊ทธ๋ฆฌ๊ณ  error์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ

import { customGet } from '@utils/customFetch.js';
import { BASIC_URL } from '@src/constants/constants.js';

// ์„œ๋ฒ„๊ฐ€ ์ผœ์ ธ์žˆ์–ด์•ผ์ง€๋งŒ fetch๊ฐ€ ๋˜๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์— ๋Œ€ํ•œ ์˜์กด์„ฑ์„ ๋‚ฎ์ถ”๋Š” ๋ฐฉ๋ฒ•์€ ์—†์„๊นŒ..?
// ์„œ๋ฒ„๊ฐ€ ๊บผ์ง€๋ฉด test๋„ ์‹คํŒจ๊ฐ€ ๋˜์–ด๋ฒ„๋ฆฌ๋‹ˆ๊นŒ!
// ์ถ”ํ›„์— mock server ์•Œ์•„๋ณด๊ธฐ
describe('Custom GET', () => {
  it('About Left Issue data', async () => {
    const issues = (
        await customGet(`${BASIC_URL}/issues`).then((res) => res.json())
    )[0];
    const leftIssues = issues.leftRollingData;
    const firstIssue = leftIssues[0];
    expect(firstIssue).toEqual(
        "๋‚ฉ์น˜ยท์‚ด์ธ 3์ธ์กฐ ์˜์žฅ์‹ฌ์‚ฌโ€ฆ'์™œ ์ฃฝ์˜€๋‚˜' ๋ฌป์ž ๋ฌต๋ฌต๋ถ€๋‹ต",
    );
  });

  it('About Error', async () => {
    const mockPromise = async () => await customGet(`${BASIC_URL}/none`);
    await expect(mockPromise).rejects.toThrow(
        new Error('Error: 404 Not Found'),
    );
  });
});

fetch์— ๊ด€ํ•œ ํ…Œ์ŠคํŠธ๋Š” ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋ผ ํฌ๊ฒŒ ๋‹ค๋ฅผ ๊ฒŒ ์—†๋Š”๋ฐ, error๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ถ€๋ถ„์ด ์žฌ๋ฏธ์žˆ์—ˆ๋‹ค. ์ผ๋ถ€๋Ÿฌ ์—๋Ÿฌ๋ฅผ ๋‚ด๊ณ  ๊ทธ์— ๋Œ€ํ•œ promise๋ฅผ reject ์ฒ˜๋ฆฌํ•˜์—ฌ ์—๋Ÿฌ๋ฅผ ์žก์•„๋‚ด๊ณ  ๊ทธ ๋•Œ์˜ ๊ฐ’๊ณผ ์˜ˆ์ƒ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค. ์•ž์œผ๋กœ๋„ ๋‹ค์–‘ํ•œ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด๋ด์•ผ๊ฒ ๋‹ค!