类型错误:无法读取未定义的属性(读取"获取人员列表")



我的测试规格出现错误:

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();
});

最新更新