Angular / Jasmine:没有提供叠加层!还有如何测试 material 对话框
Angular / Jasmine: No provider for Overlay! Also how to test a material dialog
我正在尝试测试一个 angular material 对话框,具体来说,我想测试它在关闭对话框时是否会修改路由。为此,我不想 mock/stub 退出对话(我不这么认为?),因为我希望它 运行 执行重新路由的实际 .subscribe 方法。
我在实际对话中遇到两个错误:
this.dialogRef.afterClosed is not a function
登录对话框-component.spec.ts
describe('LoginDialogComponent', () => {
let component: LoginDialogComponent;
let fixture: ComponentFixture<LoginDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LoginDialogComponent],
imports: [
RouterTestingModule.withRoutes([]),
MatDialogModule
],
providers: [
{provide: MatDialog},
{provide: MAT_DIALOG_DATA, useValue: {}},
{provide: MatDialogRef, useValue: {}},
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
我遇到的第二个错误是对打开对话框的组件的测试。它报告:
NullInjectorError: R3InjectorError(DynamicTestModule)[MatDialog -> Overlay -> Overlay]:
NullInjectorError: No provider for Overlay!
打开我的对话框的组件测试:login.component.spec.ts
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
providers: [
{ provide: MatDialog },
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: MatDialogRef, useValue: {}}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
LoginComponent 本身并不真正需要任何测试,但如上所述,它给了我“没有覆盖提供者”,大概是因为构造函数是:
constructor(
private dialog: MatDialog
) { }
LoginComponent 然后打开 LoginDialog。
我想在 LoginDialog 中测试的代码是:
ngOnInit(): void {
this.dialogRef.afterClosed().subscribe(_ =>
this.router.navigate(['', {outlets: {login: null}}])
);
}
我想确保路由器在对话框关闭时确实导航离开。
所以我的问题是
- 如何将真实的 dialogRef 传递给 LoginDialog 的构造函数?
- 如何消除“没有提供者覆盖”错误?
顺便说一句,如果我改变
{ provide: MatDialogRef, useValue {})
至:
{ provide: MatDialogRef }
(所以我大概是想传递一个实际的 MatDialogRef)
错误从
this.dialogRef.afterClosed is not a function
至:
Can't resolve all parameters for MatDialogRef: (?, ?).
谢谢。
尝试:
在 login-dialog-component.spec.ts
中删除整个 providers
数组,因为我们不应该模拟 MatDialog
的内部工作,而是在 imports
中保留 MatDialogModule
.
在login.component.spec.ts
中,在TestBed.configureTestingModule
的imports
数组中添加MatDialogModule
,并删除前面提到的providers
数组。
我正在尝试测试一个 angular material 对话框,具体来说,我想测试它在关闭对话框时是否会修改路由。为此,我不想 mock/stub 退出对话(我不这么认为?),因为我希望它 运行 执行重新路由的实际 .subscribe 方法。
我在实际对话中遇到两个错误:
this.dialogRef.afterClosed is not a function
登录对话框-component.spec.ts
describe('LoginDialogComponent', () => {
let component: LoginDialogComponent;
let fixture: ComponentFixture<LoginDialogComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [LoginDialogComponent],
imports: [
RouterTestingModule.withRoutes([]),
MatDialogModule
],
providers: [
{provide: MatDialog},
{provide: MAT_DIALOG_DATA, useValue: {}},
{provide: MatDialogRef, useValue: {}},
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginDialogComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
我遇到的第二个错误是对打开对话框的组件的测试。它报告:
NullInjectorError: R3InjectorError(DynamicTestModule)[MatDialog -> Overlay -> Overlay]:
NullInjectorError: No provider for Overlay!
打开我的对话框的组件测试:login.component.spec.ts
describe('LoginComponent', () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ],
providers: [
{ provide: MatDialog },
{ provide: MAT_DIALOG_DATA, useValue: {} },
{ provide: MatDialogRef, useValue: {}}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
LoginComponent 本身并不真正需要任何测试,但如上所述,它给了我“没有覆盖提供者”,大概是因为构造函数是:
constructor(
private dialog: MatDialog
) { }
LoginComponent 然后打开 LoginDialog。
我想在 LoginDialog 中测试的代码是:
ngOnInit(): void {
this.dialogRef.afterClosed().subscribe(_ =>
this.router.navigate(['', {outlets: {login: null}}])
);
}
我想确保路由器在对话框关闭时确实导航离开。
所以我的问题是
- 如何将真实的 dialogRef 传递给 LoginDialog 的构造函数?
- 如何消除“没有提供者覆盖”错误?
顺便说一句,如果我改变
{ provide: MatDialogRef, useValue {})
至:
{ provide: MatDialogRef }
(所以我大概是想传递一个实际的 MatDialogRef)
错误从
this.dialogRef.afterClosed is not a function
至:
Can't resolve all parameters for MatDialogRef: (?, ?).
谢谢。
尝试:
在 login-dialog-component.spec.ts
中删除整个 providers
数组,因为我们不应该模拟 MatDialog
的内部工作,而是在 imports
中保留 MatDialogModule
.
在login.component.spec.ts
中,在TestBed.configureTestingModule
的imports
数组中添加MatDialogModule
,并删除前面提到的providers
数组。