提问人:priyansh kasera 提问时间:11/7/2023 更新时间:11/7/2023 访问量:26
在单元测试中出现错误:无法读取未定义的属性(读取“订阅”)
Getting Error Cannot read properties of undefined (reading 'subscribe') in Unit testing
问:
我正在尝试用 angular 为我的组件编写一个单元测试,但是当它调用 Api 时,它会从响应中取消定义,我不知道如何处理这个问题,因为这是我第一次用 angular 编写单元测试,请帮忙!
这是我对组件 UserProfile 的单元测试的代码
import { ComponentFixture, TestBed,async } from '@angular/core/testing';
import { ApiService } from 'src/app/services/api.service';
import { UserProfileComponent } from './user-profile.component';
describe('UserProfileComponent', () => {
let component: UserProfileComponent;
let fixture: ComponentFixture<UserProfileComponent>;
let apiService: jasmine.SpyObj<ApiService>;
beforeEach(() => {
apiService = jasmine.createSpyObj('ApiService', ['getUser', 'getRepo']);
TestBed.configureTestingModule({
declarations: [UserProfileComponent],
providers: [{ provide: ApiService, useValue: apiService }],
});
fixture = TestBed.createComponent(UserProfileComponent);
component = fixture.componentInstance;
// Initialize test data
component.userDetail = { public_repos: 20 };
component.userName = 'testuser';
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
这是我的 UserProfile 组件代码
import { Component, Input, OnInit } from '@angular/core';
import { ApiService } from 'src/app/services/api.service';
@Component({
selector: 'app-user-profile',
templateUrl: './user-profile.component.html',
styleUrls: ['./user-profile.component.scss'],
})
export class UserProfileComponent implements OnInit {
@Input() userDetail: any;
@Input() userName: any;
perPage: number;
pageNo: number;
isLoading: boolean;
repoList: any;
noOfPages: any[];
options: { value: number; label: number }[] = [];
constructor(private apiService: ApiService) {
this.perPage = 10;
this.pageNo = 1;
this.isLoading = false;
this.noOfPages = new Array(10);
for (let i = 10; i <= 100; i++) {
const tempObj = {
value: i,
label: i,
};
this.options.push(tempObj);
}
}
getUserRepos() {
this.isLoading = true;
this.apiService.getRepo(this.userName, this.perPage, this.pageNo).subscribe(
(data) => {
this.repoList = data;
setTimeout(() => {
this.isLoading = false;
}, 200);
},
(error) => {
error.log(error);
setTimeout(() => {
this.isLoading = false;
}, 200);
}
);
}
changePageNo(pageNo: number) {
this.pageNo =
pageNo <= 0
? 1
: pageNo > this.noOfPages.length
? this.noOfPages.length
: pageNo;
this.getUserRepos();
}
onPerPageNoChange() {
this.noOfPages = new Array(
Math.floor(this.userDetail.public_repos / this.perPage) + 1
);
this.pageNo = 1;
this.getUserRepos();
}
ngOnInit() {
this.noOfPages = new Array(
Math.floor(this.userDetail.public_repos / this.perPage) + 1
);
console.log(this.noOfPages)
this.getUserRepos();
}
}
服务中 getRepo 方法的代码
getRepo(githubUsername : string,perPage : number,pageNo : number){
return this.httpClient.get(`https://api.github.com/users/${githubUsername}/repos?per_page=${perPage}&page=${pageNo}`)
}
答:
0赞
Philip
11/7/2023
#1
这样做的原因是,您曾经创建一个对象,该对象将同时包含 a 和 a 方法的间谍。默认情况下,它们不会返回任何内容,但 .jasmine.createSpyObj
getUser
getRepo
undefined
您可以通过执行以下操作来更改此设置:
beforeEach(() => {
apiService = jasmine.createSpyObj('ApiService', ['getUser', 'getRepo']);
apiService.getRepo.and.returnValue(of({...})); // <--- data that should be returned by your api goes here
TestBed.configureTestingModule({
declarations: [UserProfileComponent],
providers: [{ provide: ApiService, useValue: apiService }],
});
fixture = TestBed.createComponent(UserProfileComponent);
component = fixture.componentInstance;
// Initialize test data
component.userDetail = { public_repos: 20 };
component.userName = 'testuser';
fixture.detectChanges();
});
您还可以在每个单独的测试中放置行,以根据每个测试场景的需要更改您的行为。apiService.getRepo.and.returnValue(...)
ApiService
评论