การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW
จำลองคำขอ HTTP ด้วย Mock Service Worker เพื่อทดสอบคอมโพเนนต์ที่ดึงข้อมูล
การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW เป็นบทเรียน React Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องใช้ Mock Service Worker
MSW ดักจับคำขอ HTTP ในระดับเครือข่ายโดยใช้เซอร์วิสเวิร์กเกอร์ในเบราว์เซอร์ หรืออินเตอร์เซปเตอร์ http ใน Node ทำให้จำลอง API ได้โดยไม่ต้องแก้ไขโค้ดแอปพลิเคชัน
การติดตั้ง MSW
ติดตั้ง MSW และตั้งค่าอินเตอร์เซปเตอร์ของ Node สำหรับการทดสอบด้วย Jest/Vitest
// npm install msw --save-dev
// src/mocks/handlers.ts
import { http, HttpResponse } from 'msw';
export const handlers = [
http.get('/api/users', () => {
return HttpResponse.json([{ id: 1, name: 'Alice' }]);
}),
];การตั้งค่าเซิร์ฟเวอร์จำลอง
สร้างอินสแตนซ์ setupServer พร้อมตัวจัดการของคุณ แล้วเรียก server.listen() ก่อนการทดสอบ เรียก server.resetHandlers() หลังการทดสอบแต่ละครั้ง และเรียก server.close() หลังการทดสอบทั้งหมด
import { setupServer } from 'msw/node';
import { handlers } from './handlers';
const server = setupServer(...handlers);
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());การทดสอบคอมโพเนนต์ที่ดึงข้อมูล
แสดงผลคอมโพเนนต์ที่เรียกใช้การดึงข้อมูล MSW จะดักจับคำขอและส่งคืนข้อมูลจำลอง จากนั้นตรวจสอบสิ่งที่ผู้ใช้เห็นหลังข้อมูลโหลดเสร็จ
test('shows user list after fetch', async () => {
render(<UserList />);
expect(screen.getByText('Loading...')).toBeInTheDocument();
expect(await screen.findByText('Alice')).toBeInTheDocument();
});คิวรี findBy สำหรับ UI แบบอะซิงโครนัส
คิวรี findBy จะส่งคืนพรอมิสที่เสร็จสมบูรณ์เมื่อองค์ประกอบปรากฏขึ้น โดยมีเวลาหมดเริ่มต้นไม่เกิน 1 วินาที ใช้คิวรีนี้กับเนื้อหาที่ปรากฏหลังการดำเนินการแบบอะซิงโครนัส
// findByText waits for the element to appear
const username = await screen.findByText('Alice');
expect(username).toBeInTheDocument();
// waitFor wraps assertions that need to wait
await waitFor(() => {
expect(screen.getByText('3 users')).toBeInTheDocument();
});การแทนที่ตัวจัดการในการทดสอบแต่ละครั้ง
ใช้ server.use() ภายในการทดสอบ เพื่อเพิ่มตัวจัดการแบบใช้ครั้งเดียวที่แทนที่ค่าเริ่มต้นเฉพาะในการทดสอบนั้น
test('shows error on API failure', async () => {
server.use(
http.get('/api/users', () => {
return HttpResponse.json({ message: 'Server error' }, { status: 500 });
})
);
render(<UserList />);
expect(await screen.findByText('Failed to load users')).toBeInTheDocument();
});การทดสอบสถานะกำลังโหลด
ตรวจสอบตัวบ่งชี้การโหลดทันทีหลังการแสดงผลแบบซิงโครนัส ก่อนที่ข้อมูลแบบอะซิงโครนัสจะมาถึง
test('shows loading state initially', () => {
render(<UserList />);
expect(screen.getByRole('progressbar')).toBeInTheDocument();
// or
expect(screen.getByText('Loading...')).toBeInTheDocument();
});การทดสอบคำขอ POST
กำหนดตัวจัดการ POST ที่ตรวจสอบ body ของคำขอและส่งคืนทรัพยากรที่สร้างขึ้น ยืนยันว่าองค์ประกอบแสดงสถานะสำเร็จ
server.use(
http.post('/api/users', async ({ request }) => {
const body = await request.json();
return HttpResponse.json({ id: 2, ...body }, { status: 201 });
})
);
test('creates a user', async () => {
const user = userEvent.setup();
render(<NewUserForm />);
await user.type(screen.getByLabelText('Name'), 'Bob');
await user.click(screen.getByRole('button', { name: /create/i }));
expect(await screen.findByText('User created!')).toBeInTheDocument();
});ความล่าช้าของเครือข่ายเพื่อการทดสอบที่สมจริง
เพิ่มความล่าช้าเทียมให้กับตัวจัดการเพื่อทดสอบส่วนติดต่อผู้ใช้ขณะโหลดอย่างละเอียดมากขึ้น โดยใช้ยูทิลิตี delay ของ MSW
import { delay } from 'msw';
http.get('/api/users', async () => {
await delay(200);
return HttpResponse.json([{ id: 1, name: 'Alice' }]);
})การทดสอบด้วย React Query
ห่อองค์ประกอบด้วย QueryClientProvider ใหม่สำหรับการทดสอบแต่ละครั้ง เพื่อป้องกันไม่ให้สถานะรั่วไหลระหว่างการทดสอบ
function renderWithQuery(ui: React.ReactElement) {
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
return render(
<QueryClientProvider client={queryClient}>{ui}</QueryClientProvider>
);
}การยืนยันข้อมูลคำขอ
ใช้ตัวสอดแนมคำขอภายในตัวจัดการเพื่อตรวจสอบว่าแอปพลิเคชันส่ง body หรือส่วนหัวของคำขอได้ถูกต้อง
let capturedBody: unknown;
server.use(
http.post('/api/login', async ({ request }) => {
capturedBody = await request.json();
return HttpResponse.json({ token: 'abc' });
})
);
test('sends credentials to API', async () => {
// ... submit form ...
expect(capturedBody).toEqual({ email: 'a@b.com', password: 'pass' });
});MSW ในเบราว์เซอร์สำหรับการพัฒนา
MSW ยังทำงานในเบราว์เซอร์ระหว่างการพัฒนาได้ด้วย เรียกใช้ npx msw init public/ เพื่อติดตั้งตัวทำงานบริการ และนำเข้าตัวจัดการใน main.tsx เพื่อใช้ API จำลองระหว่างการพัฒนาในเครื่อง
ตรวจสอบอย่างรวดเร็ว
คุณควรใช้คำค้นหาประเภทใดของ RTL เพื่อยืนยันเนื้อหาที่ปรากฏหลังจากการเรียก API เสร็จสมบูรณ์
สรุปทบทวน
MSW ดักจับคำขอ HTTP จริง ทำให้การทดสอบสมจริงโดยไม่ต้องเรียกใช้เซิร์ฟเวอร์จริง ใช้ server.use() เพื่อเขียนทับตัวจัดการสำหรับการทดสอบแต่ละครั้ง ใช้ findBy สำหรับการยืนยันแบบอะซิงโครนัส และห่อการทดสอบ React Query ด้วย QueryClientProvider ใหม่
คำถามที่พบบ่อย
บทเรียน “การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW”
จำลองคำขอ HTTP ด้วย Mock Service Worker เพื่อทดสอบคอมโพเนนต์ที่ดึงข้อมูล คุณปฏิบัติ React Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน
บทเรียน “การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน React Academy นี้ได้ไหม
ได้ บทเรียน React Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การทดสอบแบบผสานรวมด้วย React Testing Library
- การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW
- เริ่มต้นใช้งาน Playwright สำหรับ React
- การทดสอบฟอร์มและขั้นตอนการใช้งานตั้งแต่ต้นจนจบ