- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
您好,我正在进行单元测试并尝试覆盖我的订阅。但是它一直失败并出现错误dialogRef.afterClosed is not a function
我不确定我可以监视什么或如何监视 afterClosed() 函数,但这是我似乎无法涵盖的唯一部分。 ...
import { MatDialog } from '@angular/material/dialog';
....
constructor( private dialog: MatDialog) { }
showLogin(): void {
const dialogRef = this.dialog.open(LoginDialogComponent, {
width: '400px',
height: 'auto',
data: this.loginContext
});
dialogRef.afterClosed().subscribe(result => {
if (this.loginContext.loggedIn) {
this.showApply();
}
});
}
这是LoginDialogComponent
....
@Component({
selector: 'app-login-dialog',
templateUrl: './login-dialog.component.html',
styleUrls: ['./login-dialog.component.scss']
})
export class LoginDialogComponent implements OnInit {
constructor(
private authService: AuthService,
private alertService: AlertService,
public dialogRef: MatDialogRef<LoginState>,
@Inject(MAT_DIALOG_DATA) public data: LoginState) { }
ngOnInit() {
this.data.loggedIn = false;
}
login(loginEvent: LoginEvent): void {
this.authService.login(loginData).then(
resp => {
this.data.loggedIn = true; // feedback
this.dialogRef.close();
},
err => {
this.alertService.showAlert(err);
}
);
}
}
最佳答案
我将 Sam Tsai 的答案更进一步,并创建了一个 stub 文件以使其更加简洁。这是 stub 文件内容:
import { of } from 'rxjs';
/*
The default behavior is to test that the user clicked 'OK' in the dialog.
To reset to this behavior (if you've previously tested 'Cancel'),
call setResult(true).
If you want to test that the user clicked 'Cancel' in the dialog,
call setResult(false).
*/
export class MatDialogStub {
result: boolean = true;
setResult(val: boolean) {
this.result = val;
}
open() {
return {afterClosed: () => of(this.result) };
}
}
然后在 .spec.ts 文件中使用如下所示的 stub :
import { MatDialogStub } from '../../../../testing/mat-dialog-stub'; // <--- (import here)
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
const dialogStub = new MatDialogStub(); // <--- (declare here)
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [ MyComponent ],
providers: [
{ provide: MatDialog, useValue: dialogStub } // <--- (use here)
]
})
.compileComponents();
}));
//...
});
并且在实际测试中可以通过调用setResult()函数将返回值设置为true或false来分别模拟点击“确定”或“取消”按钮:
dialogStub.setResult(true);
或
dialogStub.setResult(false);
注意: stub 测试的默认值是“OK”,因此如果您只是测试“OK”,则不必调用该函数。
下面的测试首先模拟“取消”,然后单击“确定”按钮:
it(`should not call 'delete' when Submit button pressed and user cancels`, async(() => {
component.apis = [new Api({name: 'abc'})];
component.displayPermissions = [new Permission({name: 'abc'})];
dialogStub.setResult(false); // <--- (call the function here)
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
compiled.querySelector('button').click();
expect(permissionService.delete.calls.count()).toBe(0, 'no calls');
}));
it(`should call 'delete' once when Submit button pressed and not cancelled`, async(() => {
component.apis = [new Api({name: 'abc'})];
component.displayPermissions = [new Permission({name: 'abc'})];
dialogStub.setResult(true); // <--- (call the function here)
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
compiled.querySelector('button').click();
expect(permissionService.delete.calls.count()).toBe(1, 'one call');
}));
<小时/>
原始答案
我到处寻找一种简洁的方法来模拟 MatDialog 并消除我遇到的错误dialogRef.afterClosed is not a function。 (请参阅我在底部尝试过的一些链接)。在我尝试 Sam Tsai 对这个问题的回答之前,我发现没有什么是正确的解决方案。这是一个简单的解决方案,消除了我的所有错误,并使我能够正确测试我的应用程序。我希望在花这么多时间在所有其他链接上之前找到这个。
这是失败的单元测试;它在 ('button').click 事件上失败,因为它打开 MatDialog 并且仅在对话框返回 true 时才执行删除。我不知道如何正确模拟 MatDialog,因此会发生删除:
it("should call 'delete' once when Submit button pressed and not cancelled", async(() => {
component.apis = [new Api({name: 'abc'})];
component.displayPermissions = [new Permission({name: 'abc'})];
fixture.detectChanges();
const compiled = fixture.debugElement.nativeElement;
compiled.querySelector('button').click();
expect(permissionService.delete.calls.count()).toBe(1, 'one call');
}));
我通过添加以下内容修复了它:
describe('MyComponent', () => {
let component: MyComponent;
let fixture: ComponentFixture<MyComponent>;
const dialogRefStub = {
afterClosed() {
return of(true);
}
};
const dialogStub = { open: () => dialogRefStub };
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [ MyComponent ],
providers: [
{ provide: MatDialog, useValue: dialogStub }
]
})
.compileComponents();
}));
//...
});
我尝试过的一些链接:
关于angular - dialogRef.afterClosed 不是一个函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52968940/
我正在使用 MatDialogRef为了从组件调用模态。 关闭 ModalComponent 时,我尝试取回数据,但是 似乎什么都回不去了。 dialogRef = dialog.open(Modal
您好,我正在进行单元测试并尝试覆盖我的订阅。但是它一直失败并出现错误dialogRef.afterClosed is not a function 我不确定我可以监视什么或如何监视 afterClos
我在关闭后使用 fancybox API 时遇到问题。 当人们点击这个时我打开这个功能: 这背后的 javascript 是: $('.fancybox.iframe') .fancybox
我在我的应用程序和 Angular Material 对话框中使用了 Angular Material。 关闭对话框后,应根据单击的按钮执行操作 A 或操作 B: dialogRef.afterClo
我有这样的脚本 fancybox $.fancybox.open({ href : ''+url_param, type : 'ajax
我一直在一个有 Angular 5 和 Angular Material 的项目中工作,我试图将值传递给对话框并在对话框关闭时取回值,但由于某种原因,当对话框关闭时我变得不确定关闭。 对话框 impo
在父 html 页面中,当我单击一个链接时,fancybox 对话框打开,我在该 fancybox 中加载了一个 laravel php View 页面。 当我在 fancybox 对话框中按下“使用
我正在使用 Angular Material 模态来调用 Web 服务,以防单击确认按钮它的工作问题是,如果 Web 服务返回错误,我无法得到错误 dialogRef.afterClosed().su
我从 Karma Jasmine 收到以下错误: TypeError:无法读取未定义的属性“afterClosed” 我认真搜索过,但在 Stack Overflow 或其他来源中找不到解决方案。 这
我正在使用以下函数打开我的 mat 对话框: accept() { let dialogRef = this.dialog.open(AcceptDialogComponent, { da
我正在使用 Fancybox 2.0.6 和 jQuery 1.7.2。 我有一个 asp.net 网页,有两个更新面板,一个在左侧,一个在右侧。左侧有一个具有调查问卷结构的 Telerik RadT
我正在尝试将数据从对话框传递回用户从中打开对话框的组件。我的简单示例如下: test.component.ts import { xDialogComponent } from './../x-dia
我正在尝试在 Fancybox 2 中使用 beforeLoad 和 afterClose。 我需要在 iFrame 中隐藏 Flash 动画 - 它位于 #elanceiframe div 中 -
我是一名优秀的程序员,十分优秀!