问题描述
我从业力茉莉花中收到以下错误:TypeError: Cannot read property 'afterClosed' of undefined
I get the following error from Karma Jasmine:TypeError: Cannot read property 'afterClosed' of undefined
我进行了认真的搜索,但是在Stack Overflow或其他来源中找不到解决方案.
I searched sincerely, but I could not find a solution in Stack Overflow or in other sources.
这是我在组件中打开MatDialog
的方式:
(就像记录)
This is how I open the MatDialog
in my component:
(Like documented)
constructor(public dialog: MatDialog) {}
public openDialog(): void {
const dialogReference: MatDialogRef<any, any> = this.dialog.open(myDialogComponent, {
width: '1728px'
});
dialogReference.afterClosed().subscribe((result) => {
});
}
这是我的单元测试配置:
This is my unit test config:
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
myRequestComponent
],
imports: [
MatDialogModule,
ReactiveFormsModule
],
providers: [
{ provide: MatDialog, useValue: {} },
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(myRequestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
这是我的单元测试:
it('openDialog() should open a dialog', () => {
spyOn(component.dialog, 'open');
component.openDialog();
expect(component.dialog.open).toHaveBeenCalled();
});
我必须模拟MatDialog或MatDialogReference吗?
Do I have to mock the MatDialog or the MatDialogReference?
推荐答案
让我们逐步解决您的问题.
Lets break your issue step by step.
第一,通过注册
providers: [{ provide: MatDialog, useValue: {} }],
每当需要解析MatDialog
时,您的测试台将注入一个没有任何行为的对象(例如,实例方法/成员).
Your test bed will inject a an object with no behavior (eg. instance methods/members) whenever MatDialog
needs to be resolved.
这不是真正必要的,因为您要将MatDialogModule
导入到测试台中,因此可以解析MatDialog
的实例而不会出现问题. 此解决方案将要求您删除该行.
This isn't truly necessary, as you are importing the MatDialogModule
into your test bed, so an instance of MatDialog
can be resolved without issues. This solution will require you to remove that line.
第二,方法是:
spyOn(component.dialog, 'open')
您要在component.dialog
引用的对象中为open
实例方法安装 proxy .在这种情况下,您先前注册的空对象.
you are installing a proxy for the open
instance method in the object referenced by component.dialog
. In this case, the empty object that you registered previously.
最后,只要与之交互,代理将记录有关这些交互的信息,并将呼叫重定向到原始的open
成员.由于没有原始实现,因此一个没有返回值的函数将被替换在其位置,最终将触发accessing foo of undefined
.
Lastly, whenever interacted with, the proxy will record information about those interactions and redirect the calls to the original open
member. Because there was no original implementation, a function with no return will be used in its place, which will finally trigger the accessing foo of undefined
.
TL; DR;
删除{ provide: MatDialog, useValue: {} }
并使用以下命令模拟所需的MatDialogRef
实例:
Remove { provide: MatDialog, useValue: {} }
and use the following in order to mock the required MatDialogRef
instance:
import { EMPTY} from 'rxjs';
it('openDialog() should open a dialog', () => {
const openDialogSpy = spyOn(component.dialog, 'open')
.and
.returnValue({afterClosed: () => EMPTY});
component.openDialog();
expect(openDialogSpy).toHaveBeenCalled();
});
这篇关于在Jasmine中对MatDialog进行单元测试时,无法读取未定义的属性'afterClosed'的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!