Angular uygulamasında yapısal bir direktifi test etme
Yapısal direktifler, alt görünümün render edilmesini etkiler; kesinlikle *ngIf
kullandığınızda bu durum geçerlidir. Test etme adımları, özellik direktiflerini test etme adımlarına oldukça yakındır: özel bir şablon render etmemiz ve ardından direktifin davranışını doğrulamamız gerekiyor.
TestBed
'i yapılandırmak için MockBuilder
için ilk parametre direktifin kendisidir. Eğer bağımlılıkları varsa, ikinci parametre olarak modülünü geçmeliyiz.
beforeEach(() => MockBuilder(TargetDirective));
Sonraki adım, özel bir şablonu render etmektir. Diyelim ki direktifin seçici ifadesi [target]
. Şimdi bunu bir testte render edelim:
const fixture = MockRender(
`<div *target="value">
içerik
</div>`,
{
value: false,
}
);
İçeriğin render edilmediğini doğrulayalım.
expect(fixture.nativeElement.innerHTML).not.toContain('içerik');
MockRender
yardımıyla, fixture.point
aracılığıyla direktifin elemanına erişebiliriz ve olaylar oluşturabiliriz; ayrıca fixture.componentInstance.value
üzerinden value
değerini değiştirebiliriz.
fixture.componentInstance.value = true;
Çünkü value
artık true
, içerik render edilmelidir.
fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toContain('içerik');
Canlı örnek
import {
Directive,
Input,
TemplateRef,
ViewContainerRef,
} from '@angular/core';
import { MockBuilder, MockRender } from 'ng-mocks';
// Bu direktif `ngIf` ile aynıdır,
// yalnızca girişi gerçekten bir değere sahipse içeriğini render eder.
@Directive({
selector: '[target]',
})
class TargetDirective {
public constructor(
protected templateRef: TemplateRef<any>,
protected viewContainerRef: ViewContainerRef,
) {}
@Input() public set target(value: any) {
if (value) {
this.viewContainerRef.createEmbeddedView(this.templateRef);
} else {
this.viewContainerRef.clear();
}
}
}
describe('TestStructuralDirectiveWithoutContext', () => {
// Direktifi test etmek istediğimiz için, MockBuilder'ın ilk
// parametresi olarak onu geçiriyoruz. İkinci parametreyi atlayabiliriz,
// çünkü bağımlılık yok.
// MockBuilder'ın sözleşmesini unutmayın.
beforeEach(() => MockBuilder(TargetDirective));
it('içeriğini gizler ve render eder', () => {
const fixture = MockRender(
`
<div *target="value">
içerik
</div>
`,
{
value: false,
},
);
// Değer false olduğu için "içerik" render edilmemelidir.
expect(fixture.nativeElement.innerHTML).not.toContain('içerik');
// Değeri true yapalım ve "içeriğin" render olup olmadığını doğrulayalım.
fixture.componentInstance.value = true;
fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).toContain('içerik');
// Değeri false yapalım ve "içeriğin" gizlendiğini doğrulayalım.
fixture.componentInstance.value = false;
fixture.detectChanges();
expect(fixture.nativeElement.innerHTML).not.toContain('içerik');
});
});