У меня есть компонент Angular 6 , который имеет поля ввода.Если какое-либо из полей ввода не проходит проверку, если пользователь пытается уйти, защита активирует функцию canDeactivate
.Защита является общей, потому что эта логика должна происходить в нескольких компонентах приложения.Он прекрасно работает, но когда я пытаюсь провести модульное тестирование этого поведения, функция canDeactivate
в охране никогда не достигается.Сам охранник достигнут, но никогда не работает.Я предоставляю охрану неправильным способом?
Интерфейс компонента защиты
export interface GuardComponent {
canDeactivate: () => Observable<boolean> | Promise<boolean> | boolean;
}
CanDeactivateGuard
export class CanDeactivateGuard implements CanDeactivate<GuardComponent> {
constructor() { }
canDeactivate(component: GuardComponent): Observable<boolean> | Promise<boolean> | boolean {
return component.canDeactivate();
}
}
Компонент
export class MyComponent implements OnInit, GuardComponent {
...
canDeactivate() {
if (!this.form.invalid) {
return true;
}
this.isError = true;
return false;
}
}
spec
const routes = [
{
path: 'my-component',
component: MyComponent,
canDeactivate: [CanDeactivateGuard],
},
{
path: 'my-component-2',
component: MyComponent2
}
];
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [ RouterTestingModule.withRoutes(routes) ],
declarations: [ MyComponent, MyComponent2 ],
providers: [ CanDeactivateGuard ],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixutre.componentInstance;
fixture.detectChanges();
});
it('should restrict route change if validation fails', fakeAsync(inject([Router, Location, CanDeactivateGuard], (router: Router, location: Location, guard: CanDeactivateGuard) => {
const textbox = fixture.debugElement.query(By.css('#inputField')).nativeElement;
const canDeactivateSpy = spyOn(guard, 'canDeactivate');
const componentDeactivateSpy = spyOn(component, 'canDeactivate');
// anything lower than 0 will fail the form
textbox.value = '-10';
fixture.detectChanges();
router.navigate(['/my-page-2']).then(() => {
expect(location.path()).toBe('/my-component'); // path doesn't change because guard blocks it due to form being invalid
expect(canDeactivateSpy).toHaveBeenCalled();
expect(componentDeactivateSpy).toHaveBeenCalled();
});
})));
Проверка не пройдена, поскольку функции canDeactivate
никогда не выполняются.