我是单元测试的新手,希望有人能帮助我。我有一个叫做StudentComponent的角组件,它有如下内容:
public getAllStudents(){
this.apollo.query({
query: GETALL_STUDENTS,
}).subscribe((result: any) => {
this.students = result?.data?.getAllStudents;
this.students.forEach(element => {
element.Age = this.CalculateAge(element.DateOfBirth);
element.DateOfBirthString = this.getDateFormat(element.DateOfBirth);
});
});
}
public CalculateAge(dateOfBirth: any): number {
let age = 0;
if (dateOfBirth) {
var timeDiff = Math.abs(Date.now() - new Date(dateOfBirth).getTime());
age = Math.floor(timeDiff / (1000 * 3600 * 24) / 365.25);
}
return age;
}
getDateFormat(date: Date): string{
let dateString = ""
if(date){
dateString = formatDate(date, 'yyyy/MM/dd','en_US').toString();
}
return dateString;
}
我写的测试用例如下
describe('getAllStudents', () => {
it('makes expected calls', () => {
spyOn(component, 'getDateFormat').and.callThrough();
spyOn(component, 'CalculateAge').and.callThrough();
spyOn(apollo, 'query').and.callThrough();
component.getAllStudents();
expect(apollo.query).toHaveBeenCalled();
expect(component.getDateFormat).toHaveBeenCalled();
expect(component.CalculateAge).toHaveBeenCalled();
});
});
这给了我一个错误。"预期间谍getDateFormat已被调用。"谁能指导我解决这个问题?
问题是getAllStudents
包含异步代码。对于Observable.subscribe
,您的代码将收到可用result
的延迟通知,最有可能是在expect
被评估之后。
使用Jasmine
测试异步代码有不同的方法(参见Jasmine文档中的异步工作)。
Angular
还提供了测试异步代码的功能。例如,您可以在fakeAsync
区域执行单元测试。然后,您需要在调用getAllStudents()
之后调用tick()
。可以像这样:
it('makes expected calls', fakeAsync(() => {
// given
spyOn(component, 'getDateFormat').and.callThrough();
spyOn(component, 'CalculateAge').and.callThrough();
spyOn(apollo, 'query').and.callThrough();
// when
component.getAllStudents();
tick();
// then
expect(apollo.query).toHaveBeenCalled();
expect(component.getDateFormat).toHaveBeenCalled();
expect(component.CalculateAge).toHaveBeenCalled();
}));
请注意,您正在测试实现,而不是方法的结果。将方法
getAllStudents()
视为黑盒并检查所有students
上的Age
和DateOfBirthString
是否按预期设置更有意义。