Я новичок в угловом тестировании, и мой вопрос может быть частью «наилучшей практики в угловом тестировании».
Я ищу способ включить наименьший модуль в тестирование и переопределить часть, которая должна меня высмеивать.
Скажем, у меня есть компонент кнопки, для работы которого нужен маршрутизатор. Его модуль выглядит так:
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_SCHEMAshallow.
Например:
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();
});





RouterTestingModule для маршрутизации и навигации.
Несколько моментов здесь:
1) Вы не должны предоставлять Router себя в своем модуле виджета. Вместо этого вы должны добавить RouterModule.forRoot() к AppModule, который будет предоставлять службу Router и ее зависимости.
2) Вы не должны создавать смешанные модули Angular, что означает, что не предоставляет объявление а также в одном модуле 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 },
],
});
Если вам интересно узнать больше, вы можете оставить мою статью Тестирование и имитация зависимостей Angular в качестве ссылки на эти трудно запоминающиеся детали.
В 2020 году я написал эти статьи: