首页 > 解决方案 > Angular Unit Test - Mat Dialog 元素始终为空

问题描述

我正在尝试修复由于向组件添加对话框而失败的单元测试。

场景是,当单击按钮时,应该出现一个警告对话框,询问该过程是否应该进一步进行,或者用户是否希望不做任何更改而返回。

这是我的组件方法中的代码片段:

onDoSomething(): void {
    if (someConfition) {
        doSomething();
    } else {
        const dialogRef = this.dialog.open(DialogComponent);
        dialogRef.componentInstance.dialogText = this.WARNING_TEXT;
        dialogRef.componentInstance.isConfirmDialog = true;
        dialogRef.afterClosed().subscribe(rp => {
            if (rp.confirmed) {
                doA();
            } else {
                doB();
            }
        });
    }
}

这是我的 dialog-component.html:

<div>
<div mat-dialog-content>
    <p>{{ dialogText }}</p>
</div>
<div *ngIf="!isConfirmDialog; else warningDialog" mat-dialog-actions align="center">
    <button mat-button (click)="onNoClick()" cdkFocusInitial>OK</button>
</div>
<ng-template #warningDialog>
    <div mat-dialog-actions align="center">
        <button id="okButton" mat-button (click)="onDoConfirm()" cdkFocusInitial>OK</button>
        <button mat-button (click)="onNoClick()">Abbrechen</button>
    </div>
</ng-template>

和 ts 文件...:

@Component({
selector: 'app-dialog',
templateUrl: './dialog.component.html',
styleUrls: ['./dialog.component.css']

}) 导出类 DialogComponent 实现 OnInit {

public dialogText;

public isConfirmDialog;

constructor(
    protected dialogRef: MatDialogRef<DialogComponent>
) { }

ngOnInit(): void {
}

onNoClick(): void {
    this.dialogRef.close({ confirmed: false });
}

onDoConfirm(): void {
    this.dialogRef.close({ confirmed: true });
}

}

当我运行单元测试时,对话框在浏览器中可见: 在此处输入图像描述

但是当我尝试在我的单元 tets 中单击它时,无论我写什么查询都找不到该按钮。

这是我的测试:

fit('test my method', async () => {
    selectANnumber();
    fixture.detectChanges();
    const headerCheckbox = fixture.nativeElement.querySelectorAll('tbody tr:not(.emptyCol) checkbox');
    expect(headerCheckbox).toBeTruthy();
    const checkbox = fixture.nativeElement.querySelectorAll('tbody tr:not(.emptyCol) td checkbox');
    expect(checkbox).toBeTruthy();
    const rowCheckbox = fixture.debugElement.queryAll(By.css('input'))[1].nativeElement as HTMLInputElement;
    expect(rowCheckbox.checked).toBeFalse();
    rowCheckbox.click();
    fixture.detectChanges();
    await fixture.whenStable();
    const myButton = fixture.nativeElement.querySelectorAll('button')[1];
    myButton.click();
    fixture.detectChanges();
    await fixture.whenStable();
    fixture.detectChanges();

    const okButton = fixture.debugElement.query(By.css('#okButton')).nativeElement as HTMLInputElement;
    okButton.click();


    fixture.detectChanges();
    await fixture.whenStable();

    const card = fixture.nativeElement.querySelectorAll('.mat-card');
    expect(card).toBeTruthy();
    expect(card[0].innerText.trim()).toEqual('My job has been successfully done');
});

是不是对话框内容没有渲染到 DOM 或类似的东西中?我一点头绪都没有……

PS当我在浏览器中手动单击按钮时,它会发生它应该是什么。所以这不是功能性,而是测试什么不起作用......

有什么建议么?我真的很感激......谢谢!


编辑

测试结果:

TypeError: Cannot read property 'click' of null

建议:

在此处输入图像描述

在此处输入图像描述


解决方案:

在检查了数百万篇文章后,我发现了这篇对我有帮助的文章:

Bootstrap 模态 DOM 元素在 Angular 单元测试中不可用

我的对话框容器不在fixture.debugElement 内,也不在fixture nativeElement 内,所以我必须按如下方式引用我的按钮:

const okButton = document.body.querySelector<HTMLInputElement>('button#okButton');

标签: angularangular-materialkarma-jasmine

解决方案


推荐阅读