0Pricing
React Academy · บทเรียน

การทดสอบ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. การทดสอบแบบผสานรวมด้วย React Testing Library
  2. การทดสอบ UI แบบอะซิงก์และการเรียก API ด้วย MSW
  3. เริ่มต้นใช้งาน Playwright สำหรับ React
  4. การทดสอบฟอร์มและขั้นตอนการใช้งานตั้งแต่ต้นจนจบ
← กลับไปที่ React Academy