我正在为使用Angular 材料组件的 Angular 应用编写单元测试。而且我一直坚持以正确的方式测试使用材料表的组件,因为它具有如下所示的结构指令。
<mat-table [dataSource]="classifications$ | async">
<mat-header-row *matHeaderRowDef="displayedColumns; sticky: true"></mat-header-row>
</mat-table>
我已经搜索了Internet和StackOverflow,以找到一种更好的方法来处理它,就像可以使用ComponentInstance
的常规指令和组件一样,但是我没有找到使用的方法>结构指令。因此,为了解除封锁,我想出了一个骇人的解决方案,它有一个context
对象,该对象将成为结构指令中设置的容器。
我还需要在结构指令中调用this.viewContainer.createEmbeddedView(this.templateRef);
以获取呈现的组件,因为我还想断言它存在于模板中。 / p>
如果您知道更好的方法,请给我指路;) 预先谢谢你!
下面您可以看到我当前的测试:
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);
});
});
});