Frontend Academy · درس

محاكاة الوحدات واستدعاءات API

حاكِ وحدات ES باستخدام jest.mock()، واستبدل fetch باستخدام MSW (Mock Service Worker)، واختبر المكوّنات التي تعتمد على بيانات خارجية دون استدعاءات شبكة حقيقية.

الدرس 4 من 412 خطوة

محاكاة الوحدات واستدعاءات API درس مجاني في Frontend Academy على CoddyKit. هذا هو الدرس 4 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Frontend Academy، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Frontend Academy 4 دروس في المجموع.

لماذا نستخدم المحاكاة؟

ينبغي أن تكون اختبارات الوحدة معزولة. فاستدعاءات API الحقيقية بطيئة وغير موثوقة ومكلفة. وتستبدل المحاكاة الاعتماديات بنُسخ اختبارية مضبوطة تعيد استجابات يمكن التنبؤ بها.

jest.mock() — محاكاة الوحدات بأكملها

يستبدل jest.mock('module-path') الوحدة بأكملها بإصدارات محاكاة تلقائية. وتصبح جميع الصادرات stubs من نوع 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() — Stubs يدوية

تنشئ 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') عند محاكاة واجهات API؟

مراجعة: المحاكاة

تستبدل jest.mock() الوحدات. وتنشئ jest.fn() بدائل وهمية قابلة للتتبع. أعد ضبط المحاكيات في beforeEach. تعترض MSW طلبات HTTP على مستوى الشبكة، ما يجعلها أسلوب المحاكاة الأكثر واقعية. استخدم server.use() لتجاوزات خاصة بكل اختبار في سيناريوهات الأخطاء. استخدم المؤقتات الوهمية للتعليمات البرمجية المعتمدة على الوقت. فضّل MSW في اختبارات تكامل المكوّنات.

البدء مجانًا

تعلم HTML مع معلم ذكاء اصطناعي — مجانًا

اكتب وقم بتشغيل أكوادك الفعلية في المتصفح، واحصل على مساعدة فورية من معلم ذكاء اصطناعي متاح 24/7، واستمر من حيث توقفت على الويب أو في التطبيق.

الدورات
41
الدروس
163

الأسئلة الشائعة

هل درس «محاكاة الوحدات واستدعاءات API» مجاني؟

نعم — نص درس «محاكاة الوحدات واستدعاءات API» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Frontend Academy، انتقل إلى CoddyKit PRO. تتضمن دورة Frontend Academy 4 دروس في المجموع.

ماذا ستتعلم في «محاكاة الوحدات واستدعاءات API»؟

حاكِ وحدات ES باستخدام jest.mock()، واستبدل fetch باستخدام MSW (Mock Service Worker)، واختبر المكوّنات التي تعتمد على بيانات خارجية دون استدعاءات شبكة حقيقية. تتمرن على Frontend Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

هل أحتاج إلى خبرة سابقة لأبدأ Frontend Academy؟

لا تُشترط خبرة سابقة. Frontend Academy على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 4 من أصل 4.

كم من الوقت يستغرق درس «محاكاة الوحدات واستدعاءات API»؟

معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.

هل يمكنني كتابة وتشغيل أكواد في درس Frontend Academy هذا؟

نعم. كل درس في Frontend Academy يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.

جميع الدروس في هذه الدورة

  1. إعداد Jest والاختبارات الأساسية
  2. @testing-library/react: render وuserEvent
  3. @testing-library/vue: تركيب المكوّنات
  4. محاكاة الوحدات واستدعاءات API
← العودة إلى Frontend Academy