تايب سكريبت - كيف يمكنني اختبار وحدة لمكون يستخدم الموجّه في Angular؟
في Angular 2.0.0، أنا أقوم باختبار وحدة لمكوّن يستخدم Router. ومع ذلك، أحصل على خطأ 'المعلمات المقدمة لا تطابق أي توقيع للهدف.' في Visual Studio Code في ملف spec.ts، يتم تظليل new Router() باللون الأحمر
ما هي الصياغة الصحيحة؟
الكود الخاص بي كما يلي:
spec.ts
import { TestBed, async } from '@angular/core/testing';
import { NavToolComponent } from './nav-tool.component';
import { ComponentComm } from '../../shared/component-comm.service';
import { Router } from '@angular/router';
describe('Component: NavTool', () => {
it('should create an instance', () => {
let component = new NavToolComponent( new ComponentComm(), new Router());
expect(component).toBeTruthy();
});
});
منشئ المكون
constructor(private componentComm: ComponentComm, private router: Router) {}
الإجابة رقم 1
يمكنك أيضًا استخدام RouterTestingModule فقط وspyOn على دالة navigate بهذا الشكل
import { TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { Router } from '@angular/router';
import { MyModule } from './my-module';
import { MyComponent } from './my-component';
describe('something', () => {
let fixture: ComponentFixture<LandingComponent>;
let router: Router;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
MyModule,
RouterTestingModule.withRoutes([]),
],
}).compileComponents();
fixture = TestBed.createComponent(MyComponent);
router = TestBed.get(Router); // TestBed.inject(Router) for Angular 9+
});
it('should navigate', () => {
const component = fixture.componentInstance;
const navigateSpy = spyOn(router, 'navigate');
component.goSomewhere();
expect(navigateSpy).toHaveBeenCalledWith(['/expectedUrl']);
});
});
الإجابة رقم 2
ذلك لأن Route لديه بعض التبعيات التي يتوقع تمريرها إلى منشئه.
إذا كنت تستخدم مكونات Angular، فلا ينبغي أن تحاول إجراء اختبارات معزولة. يجب عليك استخدام بنية اختبار Angular لإعداد بيئة الاختبار. هذا يعني السماح لـ Angular بإنشاء المكون، وتركه يحقن جميع التبعيات المطلوبة، بدلاً من محاولة إنشائها بنفسك.
لتتمكن من البدء، يجب أن يكون لديك شيء مثل
import { TestBed } from '@angular/core/testing';
describe('Component: NavTool', () => {
let mockRouter = {
navigate: jasmine.createSpy('navigate')
};
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ NavToolComponent ],
providers: [
{ provide: Router, useValue: mockRouter },
ComponentComm
]
});
});
it('should click link', () => {
let fixture = TestBed.createComponent(NavToolComponent);
fixture.detectChanges();
let component: NavToolComponent = fixture.componentInstance;
component.clickLink('home');
expect(mockRouter.navigate).toHaveBeenCalledWith(['/home']);
});
});
أو شيء من هذا القبيل. تستخدم TestBed لتكوين وحدة من البداية للاختبار. تقوم بتكوينها تقريبًا بنفس الطريقة مع @NgModule.
هنا نحن فقط نقوم بمحاكاة جهاز التوجيه. بما أننا نجري اختبار وحدات فقط، قد لا نرغب في وجود مرفق التوجيه الحقيقي. نحن فقط نريد التأكد من أنه تم استدعاؤه بالوسائط الصحيحة. المحاكي والتجسس سيكونان قادرين على التقاط هذا الاستدعاء لنا.
إذا كنت تريد استخدام الموجّه الحقيقي، فعليك استخدام RouterTestingModule، حيث يمكنك تكوين المسارات. انظر مثالاً هنا وهنا
انظر أيضاً:
- وثائق Angular حول الاختبار لمزيد من الأمثلة باستخدام بنية اختبار Angular.
