我是Angular的菜鸟,但找不到用于测试对话框组件的示例。我尝试了各种可能性,但都失败了。
import { Component, Inject, OnInit } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material';
@Component({
selector: 'app-custom-confirm-dialog',
templateUrl: './custom-confirm-dialog.component.html',
styleUrls: ['./custom-confirm-dialog.component.css'],
})
export class CustomConfirmDialogComponent implements OnInit {
title: string;
paragraph: string;
confirm: string;
refuse: string;
constructor(private dialogRef: MatDialogRef<CustomConfirmDialogComponent>,
@Inject(MAT_DIALOG_DATA) data) {
this.title = data.title;
this.paragraph = data.paragraph;
this.confirm = data.confirm;
this.refuse = data.refuse;
dialogRef.keydownEvents().subscribe((e) => {
if (e.keyCode === 27) {
this.cancel();
}
});
}
ngOnInit() {
}
cancel() {
this.dialogRef.close(false);
}
accept() {
this.dialogRef.close(true);
}
}
这很简单,但我只是在尝试..:)
而且我有这个规格:
/* tslint:disable:max-classes-per-file */
/* tslint:disable:no-big-function */
import { OverlayContainer } from '@angular/cdk/overlay';
import { Component, DebugElement, Directive, ViewChild, ViewContainerRef } from '@angular/core';
import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing';
import { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/';
import { By } from '@angular/platform-browser';
import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing';
import { CustomConfirmDialogComponent } from './custom-confirm-dialog.component';
@Directive({
// tslint:disable-next-line:directive-selector
selector: 'view-container-directive',
})
class ViewContainerDirective {
constructor(public viewContainerRef: ViewContainerRef) { }
}
@Component({
selector: 'app-view-container-component',
template: `<view-container-directive></view-container-directive>`,
})
class ViewContainerComponent {
@ViewChild(ViewContainerDirective) childWithViewContainer: ViewContainerDirective;
get childViewContainer() {
return this.childWithViewContainer.viewContainerRef;
}
}
describe('CustomConfirmDialogComponent', () => {
let dialog: MatDialog;
let overlayContainerElement: HTMLElement;
let testViewContainerRef: ViewContainerRef;
let viewContainerFixture: ComponentFixture<ViewContainerComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
ViewContainerComponent,
ViewContainerDirective,
CustomConfirmDialogComponent,
],
imports: [
MatDialogModule, // module of material modules I use
],
providers: [
{ provide: OverlayContainer, useFactory: () => {
overlayContainerElement = document.createElement('div');
return { getContainerElement: () => overlayContainerElement };
}},
],
});
TestBed.overrideModule(BrowserDynamicTestingModule, {
// not sure why I needed this, but error message told me to include it
set: {
entryComponents: [ CustomConfirmDialogComponent ],
},
});
TestBed.compileComponents();
}));
beforeEach(() => {
viewContainerFixture = TestBed.createComponent(ViewContainerComponent);
viewContainerFixture.detectChanges();
testViewContainerRef = viewContainerFixture.componentInstance.childViewContainer;
});
beforeEach(inject([MatDialog], (d: MatDialog) => {
dialog = d;
}));
describe('Save and Cancel', () => {
let dialogRef: MatDialogRef<CustomConfirmDialogComponent, any>;
let afterCloseCallback: jasmine.Spy;
beforeEach(() => {
dialogRef = dialog.open(CustomConfirmDialogComponent, {
viewContainerRef: testViewContainerRef,
data: {
// DialogData goes here
}});
afterCloseCallback = jasmine.createSpy('afterClose callback');
dialogRef.afterClosed().subscribe(afterCloseCallback);
});
it('should return input on save if no edits', async(() => {
// no edits
// click save
const saveButton: DebugElement = viewContainerFixture.debugElement.query(By.css('#acceptBtn'));
saveButton.triggerEventHandler('click', null);
viewContainerFixture.detectChanges();
viewContainerFixture.whenStable().then(() => {
expect(afterCloseCallback).toHaveBeenCalled();
expect(dialogRef.componentInstance).toBeFalsy(); // is closed
});
}));
it('should return undefined if cancelled', async(() => {
// no edits
// click cancel
const cancelButton: DebugElement = viewContainerFixture.debugElement.query(By.css('#cancelBtn'));
cancelButton.triggerEventHandler('click', null);
viewContainerFixture.detectChanges();
viewContainerFixture.whenStable().then(() => {
expect(afterCloseCallback).toHaveBeenCalledWith(undefined);
expect(dialogRef.componentInstance).toBeFalsy(); // is closed
});
}));
});
});
这是我的html:
<div class="Modal-BG">
<div class="row">
<div class="col-10"></div>
<div class="col-2">
<button hotkey="{27: 'click'}" class="float-right button-esc" (click)="cancel()"><img class="remove"/></button>
<caption class="float-right">ESC</caption>
</div>
</div>
<div clas="row">
<p class="title">{{title}}</p>
</div>
<div clas="row">
<p class="paragraph">{{paragraph}}</p>
</div>
<div class="Separator"></div>
<mat-dialog-actions>
<div class="float-right">
<button type="button" id="#cancelBtn" class="Button-bg-cancel" (click)="cancel()">{{ refuse }}</button>
<button type="button" id="#acceptBtn" class="Button-bg-confirm" (click)="accept()">{{ confirm }}</button>
</div>
</mat-dialog-actions>
</div>
但是当我运行测试时,出现以下错误:
HeadlessChrome 0.0.0(Linux 0.0.0)CustomConfirmDialogComponent保存 如果没有编辑失败,则“取消”和“取消”应返回保存时的输入 失败:无法读取null的属性'triggerEventHandler' TypeError:无法读取null的属性'triggerEventHandler'
我认为它可以找到模拟点击事件的按钮,但我不知道如何解决
有什么想法吗?
谢谢!
答案 0 :(得分:1)
在bounds
测试中,'should return input on save if no edits'
是saveButton
,因为null
部分无法找到按钮。原因是模板代码中不需要viewContainerFixture.debugElement.query(By.css('#acceptBtn'));
。
使用以下模板代码,应在测试中找到按钮:
#