Frontend Academy · บทเรียน

การจำลองโมดูลและการเรียก API

จำลอง ES modules ด้วย jest.mock() แทนที่ fetch ด้วย MSW (Mock Service Worker) และทดสอบคอมโพเนนต์ที่พึ่งพาข้อมูลภายนอกโดยไม่ต้องเรียกเครือข่ายจริง

บทเรียน 4 จาก 412 ขั้นตอน

การจำลองโมดูลและการเรียก API เป็นบทเรียน Frontend Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Frontend Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน

เหตุใดจึงต้องจำลอง

การทดสอบหน่วยควรแยกออกจากกัน การเรียก API จริงช้า ไม่แน่นอน และมีค่าใช้จ่าย การจำลองจะแทนที่การพึ่งพาด้วยตัวแทนสำหรับการทดสอบที่ควบคุมได้ ซึ่งส่งคืนคำตอบที่คาดเดาได้

jest.mock() — จำลองทั้งมอดูล

jest.mock('module-path') จะแทนที่ทั้งมอดูลด้วยรุ่นที่จำลองโดยอัตโนมัติ การส่งออกทั้งหมดจะกลายเป็นสตับ jest.fn() เรียกใช้ mockReturnValue หรือ mockResolvedValue เพื่อตั้งค่าที่ส่งคืน

jest.mock('./api');
import { fetchUser } from './api';

(fetchUser as jest.Mock).mockResolvedValue({ id: 1, name: 'Alice' });

test('renders user name', async () => {
  render(<Profile userId="1" />);
  await screen.findByText('Alice');
  expect(fetchUser).toHaveBeenCalledWith('1');
});

jest.fn() — สตับแบบกำหนดเอง

jest.fn() สร้างฟังก์ชันจำลองที่คุณสามารถติดตามและควบคุมได้ เหมาะสำหรับพร็อพฟังก์ชันเรียกกลับและการพึ่งพาบริการ

const onSubmit = jest.fn();
render(<Form onSubmit={onSubmit} />);

await user.click(screen.getByRole('button', { name: /submit/i }));

expect(onSubmit).toHaveBeenCalledOnce();
expect(onSubmit).toHaveBeenCalledWith({ email: 'alice@example.com' });

การรีเซ็ตสิ่งจำลองด้วย beforeEach

รีเซ็ตสิ่งจำลองระหว่างการทดสอบ เพื่อป้องกันไม่ให้สถานะรั่วไหล ใช้ jest.clearAllMocks() ใน beforeEach

beforeEach(() => {
  jest.clearAllMocks(); // reset call counts and implementations
});

afterAll(() => {
  jest.restoreAllMocks(); // restore original implementations
});

MSW — Mock Service Worker

MSW ดักจับการเรียก fetch/XHR จริงในระดับเครือข่าย โดยใช้ Service Workers (เบราว์เซอร์) หรือตัวดักจับของ Node.js (การทดสอบ) ให้เขียนตัวจัดการคำขอที่ส่งคืนคำตอบจำลอง

import { setupServer } from 'msw/node';
import { http, HttpResponse } from 'msw';

const server = setupServer(
  http.get('/api/users', () => {
    return HttpResponse.json([{ id: 1, name: 'Alice' }]);
  })
);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

การแทนที่ตัวจัดการของ MSW สำหรับการทดสอบแต่ละรายการ

แทนที่ตัวจัดการเริ่มต้นสำหรับสถานการณ์การทดสอบเฉพาะรายการ

test('handles server error', async () => {
  server.use(
    http.get('/api/users', () => new HttpResponse(null, { status: 500 }))
  );

  render(<UserList />);
  await screen.findByText(/server error/i);
});

การจำลอง localStorage

ใช้ jest.spyOn เพื่อจำลองเมธอดของ Web Storage ในการทดสอบที่ใช้ localStorage

beforeEach(() => {
  const store: Record<string, string> = {};
  jest.spyOn(Storage.prototype, 'getItem').mockImplementation((key) => store[key] ?? null);
  jest.spyOn(Storage.prototype, 'setItem').mockImplementation((key, val) => { store[key] = val; });
});

การจำลองตัวจับเวลา

jest.useFakeTimers() จะแทนที่ setTimeout/setInterval ด้วยเวอร์ชันที่ Jest ควบคุมได้ ส่วน jest.runAllTimers() จะเร่งตัวจับเวลาทั้งหมดให้ทำงานจนเสร็จทันที

jest.useFakeTimers();

test('shows toast for 3 seconds', () => {
  render(<Toast message="Saved!" />);
  expect(screen.getByText('Saved!')).toBeInTheDocument();

  jest.advanceTimersByTime(3000);
  expect(screen.queryByText('Saved!')).not.toBeInTheDocument();
});

afterEach(() => jest.useRealTimers());

รูปแบบโรงงานโมดูล

สำหรับ TypeScript ฟังก์ชันโรงงานของโมดูลจำลองจะคืนค่าชนิดข้อมูลที่ถูกต้อง

jest.mock('./services/auth', () => ({
  login: jest.fn().mockResolvedValue({ token: 'test-token' }),
  logout: jest.fn()
}));

การทดสอบด้วยภาพบันทึก — ใช้อย่างพอเหมาะ

การทดสอบด้วยภาพบันทึกจะจัดเก็บตัวแทนผลลัพธ์ของคอมโพเนนต์ในรูปแบบอนุกรม และล้มเหลวหากผลลัพธ์นั้นเปลี่ยนแปลง การสร้างทำได้ง่าย แต่ก็อาจทำให้เกิดผลบวกลวงที่รบกวนได้ ควรใช้เฉพาะกับคอมโพเนนต์แสดงผลที่เสถียรและไม่มีผลข้างเคียง

ตรวจสอบอย่างรวดเร็ว

ข้อได้เปรียบหลักของ MSW เหนือ jest.mock('fetch') สำหรับการจำลองเอพีไอคืออะไร

ทบทวน: การจำลอง

jest.mock() จะแทนที่โมดูล ส่วน jest.fn() จะสร้างสตับที่ติดตามการทำงานได้ รีเซ็ตการจำลองใน beforeEach โดย MSW จะดักจับ HTTP ในระดับเครือข่าย ซึ่งเป็นแนวทางการจำลองที่สมจริงที่สุด ใช้การแทนที่ server.use() รายการต่อการทดสอบสำหรับกรณีข้อผิดพลาด ใช้ตัวจับเวลาเสมือนกับโค้ดที่ขึ้นอยู่กับเวลา และควรเลือกใช้ MSW สำหรับการทดสอบการผสานรวมคอมโพเนนต์

เริ่มต้นได้ฟรี

เรียนรู้ HTML ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
41
บทเรียน
163

คำถามที่พบบ่อย

บทเรียน “การจำลองโมดูลและการเรียก API” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การจำลองโมดูลและการเรียก API” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Frontend Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Frontend Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การจำลองโมดูลและการเรียก API”

จำลอง ES modules ด้วย jest.mock() แทนที่ fetch ด้วย MSW (Mock Service Worker) และทดสอบคอมโพเนนต์ที่พึ่งพาข้อมูลภายนอกโดยไม่ต้องเรียกเครือข่ายจริง คุณปฏิบัติ Frontend Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Frontend Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Frontend Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “การจำลองโมดูลและการเรียก API” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Frontend Academy นี้ได้ไหม

ได้ บทเรียน Frontend Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การตั้งค่า Jest และการเขียนเทสต์พื้นฐาน
  2. @testing-library/react: render และ userEvent
  3. @testing-library/vue: การเมานต์คอมโพเนนต์
  4. การจำลองโมดูลและการเรียก API
← กลับไปที่ Frontend Academy