0Pricing
Angular Academy · درس

محاكاة الخدمات والتبعيات

وفّر بدائل اختبارية عبر DI

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

سبب محاكاة الاعتماديات

يجب أن يعزل اختبار المكوّن المكوّن نفسه. فإذا كان يحقن خدمة تعتمد على HttpClient، فلن ترغب في إجراء طلبات شبكة حقيقية. بدلًا من ذلك، وفّر بديلًا اختباريًا: كائنًا وهميًا يعيد بيانات تتحكم فيها، حتى تكون الاختبارات سريعة وحتمية.

توفير بديل وهمي باستخدام useValue

أبسط بديل اختباري هو كائن عادي توفّره باستخدام useValue. وفّره تحت رمز الحقن نفسه الذي يطلبه المكوّن.

const fakeApi = { getUser: () => of({ name: 'Ada' }) };
TestBed.configureTestingModule({
  imports: [ProfileComponent],
  providers: [{ provide: UserApi, useValue: fakeApi }],
});

اختبارات Jasmine الوهمية

تنشئ jasmine.createSpyObj بديلًا وهميًا يحتوي على أساليب تجسس، بحيث يمكنك تحديد القيم المُعادة والتحقق من الاستدعاءات معًا.

const apiSpy = jasmine.createSpyObj<UserApi>('UserApi', ['getUser']);
apiSpy.getUser.and.returnValue(of({ name: 'Ada' }));
TestBed.configureTestingModule({
  providers: [{ provide: UserApi, useValue: apiSpy }],
});

التحقق من استدعاء الخدمة

بعد تنفيذ إجراء على المكوّن، تحقّق من أن الكائن التجسسي تلقى الوسائط المتوقعة.

fixture.componentInstance.load(7);
fixture.detectChanges();
expect(apiSpy.getUser).toHaveBeenCalledWith(7);
expect(apiSpy.getUser).toHaveBeenCalledTimes(1);

إرجاع Observables من البدائل الوهمية

غالبًا ما تعيد الخدمات Observables. استخدم of() من RxJS للنجاح المتزامن، وthrowError() لحالات الفشل، حتى تتمكن من اختبار كلا المسارين.

import { of, throwError } from 'rxjs';

apiSpy.getUser.and.returnValue(of({ name: 'Ada' }));     // success
apiSpy.getUser.and.returnValue(throwError(() => new Error('boom'))); // error

useClass للبدائل الوهمية القابلة لإعادة الاستخدام

عندما يُعاد استخدام بديل وهمي في العديد من المواصفات، عرّف فئة واربطها باستخدام useClass.

class FakeUserApi {
  getUser() { return of({ name: 'Test' }); }
}
TestBed.configureTestingModule({
  providers: [{ provide: UserApi, useClass: FakeUserApi }],
});

محاكاة HttpClient باستخدام HttpTestingController

لاختبار الخدمات التي تستدعي HTTP من دون محاكاة الخدمة بأكملها، استورد provideHttpClientTesting() وفرّغ الطلبات عبر HttpTestingController.

import { provideHttpClient } from '@angular/common/http';
import { provideHttpClientTesting, HttpTestingController } from '@angular/common/http/testing';

TestBed.configureTestingModule({
  providers: [provideHttpClient(), provideHttpClientTesting()],
});

تفريغ طلب HTTP

توقّع طلبًا، واستجب له ببيانات وهمية، ثم تحقّق من عدم بقاء استدعاءات غير متوقعة.

const http = TestBed.inject(HttpTestingController);
service.load();
const req = http.expectOne('/api/users/7');
expect(req.request.method).toBe('GET');
req.flush({ name: 'Ada' });
http.verify();

تجاوز موفّر لكل مواصفة اختبار

قد يحتاج أحد الاختبارات أحيانًا إلى محاكاة وهمية مختلفة. استخدم TestBed.overrideProvider() قبل createComponent.

TestBed.overrideProvider(UserApi, {
  useValue: { getUser: () => throwError(() => new Error('fail')) },
});
const fixture = TestBed.createComponent(ProfileComponent);

محاكاة القدر الكافي فقط

تنفّذ المحاكاة الجيدة الطرق التي يستخدمها المكوّن فعليًا فقط. الإفراط في المحاكاة يربط اختبارك بالتفاصيل الداخلية، بينما يؤدي نقص المحاكاة إلى تسرّب الآثار الجانبية الحقيقية. طابق العقد العام الذي يعتمد عليه المكوّن.

تتبّع أساليب الخدمة الحقيقية

يمكنك أيضًا الإبقاء على خدمة حقيقية، مع تتبّع أسلوب واحد منها باستخدام spyOn(instance, 'method')؛ وهذا مفيد عندما تكون معظم الخدمة غير ضارة، لكن يجب اعتراض استدعاء واحد.

const svc = TestBed.inject(AnalyticsService);
spyOn(svc, 'track');
fixture.componentInstance.onClick();
expect(svc.track).toHaveBeenCalledWith('click');

تحقّق سريعًا

كيف تجعل المحاكاة الوهمية تؤكد الاستدعاءات وتتحكم في القيم المُعادة في الوقت نفسه؟

مراجعة

استبدلت التبعيات الحقيقية بمحاكاة وهمية باستخدام useValue وuseClass وJasmine spies؛ وأعدت Observables باستخدام of/throwError؛ واختبرت HTTP عبر HttpTestingController؛ وتجاوزت الموفّرات لكل مواصفة اختبار. لا تحاكِ إلا العقد الذي يستخدمه المكوّن.

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

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

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

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

وفّر بدائل اختبارية عبر DI تتمرن على Angular Academy مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.

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

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

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

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

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

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

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

  1. TestBed وتجهيزات المكوّنات
  2. اختبار المدخلات والمخرجات وDOM
  3. محاكاة الخدمات والتبعيات
  4. اختبار الإشارات والتعليمات البرمجية غير المتزامنة
← العودة إلى Angular Academy