#angular #testing #module #karma-jasmine
#angular #тестирование #модуль #karma-jasmine
Вопрос:
Я новичок в тестировании angular, и мой вопрос может быть частью «наилучшей практики в тестировании angular».
Я ищу способ включить в тестирование наименьший модуль и переопределить какую-то часть, над которой мне нужно издеваться.
Допустим, у меня есть компонент button, для работы которого нужен маршрутизатор. Его модуль выглядит так :
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MyButtonComponent } from './mybutton.component';
import { Router } from '@angular/router';
@NgModule({
imports: [
CommonModule,
],
declarations: [
MyButtonComponent,
],
exports: [
MyButtonComponent,
],
providers: [
Router,
]
})
export class MyButtonModule { }
Теперь я хочу протестировать это следующим образом :
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { MyButtonModule } from './viewer-button.module';
import { RouterTestingModule } from '@angular/router/testing';
// Tests Begining
describe('ViewerButtonComponent', () => {
let component: MyButtonComponent;
let fixture: ComponentFixture<MyButtonComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
ViewerButtonModule,
RouterTestingModule.withRoutes([]),
],
})
.compileComponents();
fixture = TestBed.createComponent(MyButtonComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('#should create the component', () => {
expect(component).toBeTruthy(' fail at creation');
});
});
Но Router
не перегружает RouterTestingModule
импорт. (получена Can't resolve all parameters for Router: (?, ?, ?, ?, ?, ?, ?, ?).
ошибка)
Я знаю, что лучший способ для этого примера — только объявить MyButtonComponent, затем импортировать RouterTestingModule, но я спрашиваю, есть ли способ сделать это с более крупным компонентом без NO_ERRORS_SCHEMA
мелочей.
Например:
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
// my childs component module
MyChildComponentModule1,
MyChildComponentModule2,
...
MyChildComponentModuleX,
//the modules that mock what needed (or use custom mock in the providers part)
RouterTestingModule,
HttpClientTestingModule,
....
SomethingTestingModule
],
})
.compileComponents();
fixture = TestBed.createComponent(MyButtonComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
Ответ №1:
RouterTestingModule
Предназначен для заглушения маршрутизации и навигации.
Здесь несколько моментов:
1) Вы не должны указывать Router
себя в своем модуле виджета. Вместо этого вы должны добавить RouterModule.forRoot()
в AppModule
, который будет предоставлять Router
сервис и его зависимости.
2) Вы не должны создавать смешанные модули Angular, то есть не предоставлять и объявлять в одном угловом модулях.
3) Порядок импорта модулей Angular имеет значение. При таком заказе импорта поставщик RouterTestingModule
переопределит Router
поставщика из ViewButtonModule
.
TestBed.configureTestingModule({
imports: [
ViewerButtonModule,
RouterTestingModule.withRoutes([]),
],
});
4) Вы всегда можете переопределить поставщика, используя модуль тестирования Angular. Например
TestBed.overrideProvider(Router, { useValue: routerStub });
или
TestBed.configureTestingModule({
providers: [
{ provide: Router, useValue: routerStub },
],
});
Если вам интересно узнать больше, вы можете сохранить мою статью о тестировании и подделке угловых зависимостей в качестве ссылки на эти трудно запоминающиеся детали.
В 2020 году я написал эти статьи: