การจำลองโมดูลและการเรียก API
จำลอง ES modules ด้วย jest.mock() แทนที่ fetch ด้วย MSW (Mock Service Worker) และทดสอบคอมโพเนนต์ที่พึ่งพาข้อมูลภายนอกโดยไม่ต้องเรียกเครือข่ายจริง
การจำลองโมดูลและการเรียก 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การตั้งค่า Jest และการเขียนเทสต์พื้นฐาน
- @testing-library/react: render และ userEvent
- @testing-library/vue: การเมานต์คอมโพเนนต์
- การจำลองโมดูลและการเรียก API