Я пишу юнит-тесты для приложения Angular , в котором используются Angular Material Components . И я застрял с тестированием компонента, который использует Таблица материалов надлежащим образом, потому что он имеет структурные директивы , как показано ниже.
<mat-table [dataSource]="classifications$ | async">
<mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
</mat-table>
Я искал в Интернете и StackOverflow, чтобы найти лучший способ справиться с ним, как вы можете с обычными директивами и компонентами, для которых вы можете получить ComponentInstance
, но я не нашел способ сделать это с структурным директивы . Поэтому, чтобы разблокировать мой билет, я пришел к этому хакерскому решению, чтобы иметь объект context
, который будет контейнером для того, что устанавливается в структурной директиве .
Мне также нужно вызвать this.viewContainer.createEmbeddedView(this.templateRef);
в структурной директиве , чтобы получить визуализированный компонент, потому что я также хочу утверждать , что он присутствует в шаблоне.
Если вы знаете лучший способ, пожалуйста, покажите мне путь;)
Заранее спасибо!
Ниже вы можете увидеть мой текущий тест:
import { Component, Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
const context: any = {};
@Directive({ selector: '[appShow]' })
export class ShowDirective {
constructor(
private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
) {}
@Input() set appShow(show: boolean) {
context.show = show;
this.viewContainer.createEmbeddedView(this.templateRef);
}
}
@Component({
template: `
<h1>STRUCTURAL DIRECTIVE TEST displayExtraHeader: {{displayExtraHeader}}</h1>
<h2 *appShow="displayExtraHeader">Lorem ipsum</h2>
`,
})
class StructuralDirectiveComponent {
displayExtraHeader = true;
}
describe('Structural Directive', () => {
let component: StructuralDirectiveComponent;
let fixture: ComponentFixture<StructuralDirectiveComponent>;
let compiled: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
ShowDirective,
StructuralDirectiveComponent,
],
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(StructuralDirectiveComponent);
compiled = fixture.debugElement.nativeElement;
component = fixture.componentInstance;
});
it('should create', () => {
expect(component).toBeTruthy();
});
describe('HTML', () => {
beforeEach(() => {
delete context.show;
component.displayExtraHeader = false;
fixture.detectChanges();
});
it('should render <h1>', () => {
expect(compiled.querySelector('h1')).not.toBeNull();
});
it('should pass displayExtraHeader to appShow', () => {
const directive1: any = fixture.debugElement.query(By.css('[appShow]'));
const directive2: any = fixture.debugElement.query(By.directive(ShowDirective));
console.log(`>>> directive1`, directive1);
console.log(`>>> directive2`, directive2);
// directive1 and directive 2 are null
// @TODO: how to get an instance of structural directive?
expect(context.show).toEqual(false);
});
});
});