Angular Jasmine 测试:使用 setTimeout 时规范没有预期
Angular Jasmine Test: SPEC HAS NO EXPECTATIONS when using setTimeout
我正在尝试为我的应用程序中的组件编写单元测试。这是一个名为 TroubleShootingPage 的非常简单的组件,如果有人在我的应用程序的其余部分遇到问题,它只会显示一个帮助页面。
所有测试都通过了,但在 Karma 的输出中我看到一个提示:SPEC HAS NO EXPECTATIONS:
本应没有期望的测试正在处理我的 TroubleShootingPage 组件中的函数 getTroubleShootingPage()
,它看起来像这样:
export interface Entry<T> {
sys: Sys;
fields: T;
toPlainObject(): object;
update(): Promise<Entry<T>>;
}
troubleShootingPage: Entry<any>;
constructor(private contentfulService: ContentfulService) {}
ngOnInit() {
this.getTroubleShootingPage("en-US")
}
getTroubleShootingPage(locale: string) {
this.contentfulService.getTroubleShootingPage(locale).then(page => {
this.troubleShootingPage = page;
...
}
}
如您所见,故障排除页面的 content/text 必须从 contentfulService 加载,并且根据用户的语言从 API (Contentful) 加载。所以我只想确保函数被调用并且从 contentfulService 返回的输入被正确分配给变量 this.troubleShootingPage
.
测试看起来像这样:
describe('TroubleshootingPageComponent', () => {
let component: TroubleshootingPageComponent;
let fixture: ComponentFixture<TroubleshootingPageComponent>;
let contentfulServiceStub: Partial<ContentfulService> = {
getTroubleShootingPage: () => {
return new Promise<Entry<any>>(() => {
return troubleShootingPageMock;
});
}
};
let troubleShootingPageMock: Entry<any>;
troubleShootingPageMock = {
fields: {
description: "Please read here for further help:",
mainText: {},
textCancelButton: "Quit",
textConfirmButton: "Continue",
title: "Need Help?"
},
toPlainObject() {
return null;
},
update() {
return null;
},
sys: {
type: "",
id: "string",
createdAt: "string",
updatedAt: "string",
locale: "string",
contentType: {
sys: null
},
},
};
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [TroubleshootingPageComponent],
schemas: [NO_ERRORS_SCHEMA],
providers: [{ provide: ContentfulService, useValue: contentfulServiceStub }]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TroubleshootingPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should get the troubleShootingPage form Contentful', () => {
component.getTroubleShootingPage("en-GB");
setTimeout(() => {
expect(component.troubleShootingPage).toEqual(troubleShootingPageMock.fields);
}, 1000)
});
// I also tried:
// it('should get the troubleShootingPage form Contentful', (done) => {
// component.getTroubleShootingPage("en-GB");
// setTimeout(() => {
// expect(component.troubleShootingPage).toEqual(troubleShootingPageMock.fields);
// done();
// }, 1000)
// });
});
我用 setTimeout()
添加了一个超时,因为没有它 component.troubleShootingPage
总是 undefined
,因为测试转到了 ecpect()
语句,在 getTroubleShootingPage 中的 Promise 之前() 函数已解决:
it('should get the troubleShootingPage form Contentful', () => {
component.getTroubleShootingPage("en-GB");
expect(component.troubleShootingPage).toEqual(troubleShootingPageMock.fields);
});
-> 这失败了,因为 component.troubleShootingPage
是 undefined
.
我该如何解决这个问题,有什么想法吗?
好的,感谢您的评论,制作函数的提示 return promise 是必要的部分:
在组件中,我只为 return 实现了一个功能:
getTroubleShootingPage(locale: string) {
this.getTroubleShootingPageFromService(locale).then(page => {
this.troubleShootingPage = page;
})
}
getTroubleShootingPageFromService(locale: string) {
return this.contentfulService.getTroubleShootingPage(locale);
}
在我的测试中,我现在有了这个,它工作正常:
it('should get the troubleShootingPage form Contentful', async () => {
spyOn(contentfulServiceStub, 'getTroubleShootingPage').and.returnValue(Promise.resolve(troubleShootingPageMock))
await component.getTroubleShootingPage("en-US");
expect(component.troubleShootingPage).toEqual(troubleShootingPageMock);
});
我正在尝试为我的应用程序中的组件编写单元测试。这是一个名为 TroubleShootingPage 的非常简单的组件,如果有人在我的应用程序的其余部分遇到问题,它只会显示一个帮助页面。
所有测试都通过了,但在 Karma 的输出中我看到一个提示:SPEC HAS NO EXPECTATIONS:
本应没有期望的测试正在处理我的 TroubleShootingPage 组件中的函数 getTroubleShootingPage()
,它看起来像这样:
export interface Entry<T> {
sys: Sys;
fields: T;
toPlainObject(): object;
update(): Promise<Entry<T>>;
}
troubleShootingPage: Entry<any>;
constructor(private contentfulService: ContentfulService) {}
ngOnInit() {
this.getTroubleShootingPage("en-US")
}
getTroubleShootingPage(locale: string) {
this.contentfulService.getTroubleShootingPage(locale).then(page => {
this.troubleShootingPage = page;
...
}
}
如您所见,故障排除页面的 content/text 必须从 contentfulService 加载,并且根据用户的语言从 API (Contentful) 加载。所以我只想确保函数被调用并且从 contentfulService 返回的输入被正确分配给变量 this.troubleShootingPage
.
测试看起来像这样:
describe('TroubleshootingPageComponent', () => {
let component: TroubleshootingPageComponent;
let fixture: ComponentFixture<TroubleshootingPageComponent>;
let contentfulServiceStub: Partial<ContentfulService> = {
getTroubleShootingPage: () => {
return new Promise<Entry<any>>(() => {
return troubleShootingPageMock;
});
}
};
let troubleShootingPageMock: Entry<any>;
troubleShootingPageMock = {
fields: {
description: "Please read here for further help:",
mainText: {},
textCancelButton: "Quit",
textConfirmButton: "Continue",
title: "Need Help?"
},
toPlainObject() {
return null;
},
update() {
return null;
},
sys: {
type: "",
id: "string",
createdAt: "string",
updatedAt: "string",
locale: "string",
contentType: {
sys: null
},
},
};
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [TroubleshootingPageComponent],
schemas: [NO_ERRORS_SCHEMA],
providers: [{ provide: ContentfulService, useValue: contentfulServiceStub }]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TroubleshootingPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should get the troubleShootingPage form Contentful', () => {
component.getTroubleShootingPage("en-GB");
setTimeout(() => {
expect(component.troubleShootingPage).toEqual(troubleShootingPageMock.fields);
}, 1000)
});
// I also tried:
// it('should get the troubleShootingPage form Contentful', (done) => {
// component.getTroubleShootingPage("en-GB");
// setTimeout(() => {
// expect(component.troubleShootingPage).toEqual(troubleShootingPageMock.fields);
// done();
// }, 1000)
// });
});
我用 setTimeout()
添加了一个超时,因为没有它 component.troubleShootingPage
总是 undefined
,因为测试转到了 ecpect()
语句,在 getTroubleShootingPage 中的 Promise 之前() 函数已解决:
it('should get the troubleShootingPage form Contentful', () => {
component.getTroubleShootingPage("en-GB");
expect(component.troubleShootingPage).toEqual(troubleShootingPageMock.fields);
});
-> 这失败了,因为 component.troubleShootingPage
是 undefined
.
我该如何解决这个问题,有什么想法吗?
好的,感谢您的评论,制作函数的提示 return promise 是必要的部分:
在组件中,我只为 return 实现了一个功能:
getTroubleShootingPage(locale: string) {
this.getTroubleShootingPageFromService(locale).then(page => {
this.troubleShootingPage = page;
})
}
getTroubleShootingPageFromService(locale: string) {
return this.contentfulService.getTroubleShootingPage(locale);
}
在我的测试中,我现在有了这个,它工作正常:
it('should get the troubleShootingPage form Contentful', async () => {
spyOn(contentfulServiceStub, 'getTroubleShootingPage').and.returnValue(Promise.resolve(troubleShootingPageMock))
await component.getTroubleShootingPage("en-US");
expect(component.troubleShootingPage).toEqual(troubleShootingPageMock);
});