我的测试规格出现错误:
TypeError: Cannot read properties of undefined (reading 'fetchPersonnelList')
import { HttpClientModule } from '@angular/common/http';
import { Component } from '@angular/core';
import {
async,
ComponentFixture,
fakeAsync,
flush,
TestBed,
tick,
} from '@angular/core/testing';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ActivatedRoute, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { SharedModule } from '../../../../../shared/shared.module';
import { PersonnelDataService } from '../services/personnel-data.service';
import { testHFSTaleSchema } from './hfs-table.schema';
import { ListPersonnelComponent } from './list-personnel.component';
const mockPersonnelDataService = {
list$: of(testHFSTaleSchema.rows),
fetchPersonnelList: function () {
return { subscribe: () => this.list$ };
},
setPageSize: function () {
return this.list$;
},
fetchPaginatedList: () => {},
};
@Component({
selector: 'app-details-personnel',
template: '',
})
export class PersonnelDetailsComponent {}
fdescribe('ListPersonnelComponent', () => {
let component: ListPersonnelComponent;
let fixture: ComponentFixture<ListPersonnelComponent>;
let activatedRoute = { url: {} } as ActivatedRoute;
let service: PersonnelDataService;
let router;
const routes = [
{
path: 'personnel-details',
component: PersonnelDetailsComponent,
},
];
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule.withRoutes(routes),
SharedModule,
BrowserAnimationsModule,
HttpClientModule,
],
declarations: [ListPersonnelComponent],
providers: [
{
provide: PersonnelDataService,
useValue: mockPersonnelDataService,
},
{ provide: ActivatedRoute, useValue: activatedRoute },
],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ListPersonnelComponent);
component = fixture.componentInstance;
router = TestBed.inject(Router);
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should call fetchPersonnelList on page Oninit', fakeAsync(() => {
component.ngOnInit();
tick(1000);
expect(service.fetchPersonnelList).toHaveBeenCalled();//error
flush();
}));
});
更新根据forestG
的建议,我通过注入服务来更新代码。当模拟服务存在时,我仍然得到一个错误:
Error: <toHaveBeenCalled> : Expected a spy, but got Function.
当添加模拟服务时,为什么我得到这个错误?
建议更新
我已经更新了我的代码如下:
it('should call fetchPersonnelList on page Oninit', fakeAsync(() => {
const fetchPersonnelListSpy = spyOn(
service,
'fetchPersonnelList'
).and.returnValue(of([]));
component.ngOnInit();
tick(1000);
expect(fetchPersonnelListSpy).toHaveBeenCalled();
flush();
}));
它的工作原理。但是我的模拟仪式有什么好处呢?如何获得模拟数据?我可以把我的数据直接放在retunValue
部分,对吗?
您应该能够直接监视服务spyOn(component.service, 'fetchPersonnelList')
并使用将调用mock函数的.callThrough()
,如果您想阻止调用mock函数并传递一些其他值,则使用.returnValue(of([]));
it('should call fetchPersonnelList on page Oninit', () => {
const fetchPersonnelListSpy = spyOn(component.service, 'fetchPersonnelList').and.callThrough();
component.ngOnInit();
expect(fetchPersonnelListSpy).toHaveBeenCalled();
});
忘记获取服务的引用:
beforeEach(() => {
fixture = TestBed.createComponent(ListPersonnelComponent);
component = fixture.componentInstance;
router = TestBed.inject(Router);
service = TestBed.inject(PersonnelDataService); // add this
fixture.detectChanges();
});