Ana içeriğe geç

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.

bilgi

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');
ipucu

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

https://github.com/help-me-mom/ng-mocks/blob/master/examples/TestStructuralDirective/test.spec.ts
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');
});
});