Директивы Angular - важная конструкция в angular, позволяющая сделать DOM манипуляциями и / или обработкой событий абстрактными.
Мы должны использовать директивы Unit Test, имитируя все зависимости с помощью жасминовых моков и шпионов.
Мы также должны использовать директивы Shallow / Deep Test с использованием конкретных компонентов (скомпилированный DOM). Разумный подход - создать TestComponent или выбрать любой компонент, который использует директиву, которую мы хотим протестировать.
Зависимости от TestComponent имитируются, но сама директива проверяет конкретный компонент (скомпилированный DOM).
Это включает в себя настройку TestBed для создания TestModule (также создает зону для тестирования) и компиляцию TestComponent с директивой для тестирования.
Давайте напишем простую директиву DisableLinkDirective, которая обеспечит [attr.disabled] = ”condition” функциональность якорных ссылок ‹a/›, чтобы они можно отключить так же, как ‹button /› изначально.
import {Directive, HostListener} from '@angular/core'; @Directive({ selector: 'a[disabled]' }) export class DisableLinkDirective { @HostListener('click', ['$event']) click(event: Event) { console.log('event', event); event.preventDefault(); } }
Теперь мы протестируем эту директиву с помощью компонента TestDisableLinkComponent, который компилирует ссылки привязки ‹a/› с атрибутом disabled.
import {DisableLinkDirective} from './disable-link.directive'; import {Component, DebugElement} from '@angular/core'; import {ComponentFixture, TestBed} from '@angular/core/testing'; import {By} from '@angular/platform-browser'; // creating a test component in the spec file @Component( { selector: 'ngx-mix-test-disable-link-directive', template: ` <div> <a id="disabled-link" disabled (click)="onClick()">Disabled</a> <a id="normal-link" (click)="onClick()">Normal</a> </div> ` } ) class TestDisableLinkComponent { toggle = false; onClick() { this.toggle = !this.toggle; } } // tests start here describe('DisableLinkDirective', () => { let component: TestDisableLinkComponent; let fixture: ComponentFixture ; beforeEach(async () => { await TestBed.configureTestingModule({ declarations: [TestDisableLinkComponent, DisableLinkDirective] }).compileComponents(); }); beforeEach(async () => { fixture = TestBed.createComponent(TestDisableLinkComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create an instance', () => { const directive = new DisableLinkDirective(); expect(directive).toBeTruthy(); }); it('should not toggle between enabled / disabled when the link with disabled attribute is clicked', async () => { const testDe: DebugElement = fixture.debugElement; const linkDe = testDe.query(By.css('#disabled-link')); const link: HTMLElement = linkDe.nativeElement; await expect(link.getAttribute('disabled')).not.toBe(null); const toggleValueBeforeClick = component.toggle; linkDe.triggerEventHandler('click', null); fixture.detectChanges(); await fixture.whenStable(); await expect(toggleValueBeforeClick).toBe(component.toggle); }); it('should toggle between enabled / disabled when the link does not have disabled attribute', async () => { const testDe: DebugElement = fixture.debugElement; const linkDe = testDe.query(By.css('#normal-link')); const link: HTMLElement = linkDe.nativeElement; await expect(link.getAttribute('disabled')).toBe(null); const toggleValueBeforeClick = component.toggle; linkDe.triggerEventHandler('click', null); fixture.detectChanges(); await fixture.whenStable(); await expect(toggleValueBeforeClick).not.toBe(component.toggle); }); });