I am trying to test a method (refreshMemberList()) that contains a subscribe, but when I run the tests I get this error from Karma. Can anyone tell me what is going on? Thank you very much in advance, such a great community you are :D
Jasmine spec list failure:
MemberListComponent > refreshMemberList refreshes members list
TypeError: Cannot read properties of undefined (reading 'subscribe')
member-list.component.ts:
describe('MemberListComponent', () => {
let component: MemberListComponent;
let fixture: ComponentFixture<MemberListComponent>;
let mockMemberListService: jasmine.SpyObj<MemberListService>;
let modalService: NgbModal;
beforeEach(async () => {
mockMemberListService = jasmine.createSpyObj(['getMembers']);
mockMemberListService.getMembers.and.returnValue(memberMockObject.fakeMemberListJSON);
await TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
{
provide: MemberListService,
useValue: mockMemberListService,
}
],
declarations: [MemberListComponent],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(MemberListComponent);
component = fixture.componentInstance;
modalService = TestBed.get(NgbModal);
});
it('refreshMemberList refreshes members list', () => {
component.refreshMemberList(memberMockObject.dataMemberMap);
fixture.detectChanges();
expect(component.members).toEqual(memberMockObject.fakeMembers);
});
});
member-list.component.ts:
export class MemberListComponent implements OnInit {
public title: String = "Members";
public showMemberDeletedAlert: Boolean;
private _memberListService: MemberListService;
public members: Member[] = [];
private dataMemberMap: Map<string, string>;
public page: number = 0;
public pageSize: number = 10;
public collectionSize: number;
public isLoading: boolean = true;
constructor(
memberListService: MemberListService,
private _modalService: NgbModal
) {
this._memberListService = memberListService;
}
ngOnInit(): void {
if(history.state.type==="delete")
this.showDeletedAlert()
this.dataMemberMap = new Map([
["name", ""],
["role", ""],
["skill", ""],
["skillLevel", ""],
["language", ""],
["languageLevel", ""]
]);
this.retrieveMemberList();
}
retrieveMemberList(): void {
this.isLoading = true;
this._memberListService.getMembers(this.dataMemberMap!, this.page, this.pageSize).subscribe((data) => {
this.members = data.memberList;
this.collectionSize = data.totalPages * this.pageSize;
this.isLoading = false;
});
}
refreshMemberList(dataMemberMap: Map<string, string>): void {
this.dataMemberMap = dataMemberMap;
this.retrieveMemberList();
}
}
CodePudding user response:
It is undefined, so can't read the subscribe property, since you want this (_memberListService) to be private, you can just use (memberListService) on the constructor as private and do not use _memberListService, it'd something like
constructor(
private memberListService: MemberListService,
private _modalService: NgbModal
) {}
and when you call getMembers you can just use this.memberListService.getMembers(...
CodePudding user response:
Why do you have a class property of type MemberListService
? Just use the dependency injection as
constructor(private memberListService: MemberListService) {}
Then just use it as:
...
this.memberListService.getMembers(...);
Also, you have all this logic been triggered right from the beginning, in your ngOnInit
lifecycle hook, which is fine; the first test you should have for this component should be this one:
it('should create', () => {
expect(component).toBeTruthy();
});
This test (which is the first test by default) verifies the successful creation of your component, so any logic within your ngOnInit
will be tested, some of this logic is calling your getMembers
service function sending 3 parameters, maybe some or all of those are undefined
?
Also, I don't know what memberMockObject
is in your test file, so for setting the return type, I would say use of
from rxjs to create an observable
:
mockMemberListService.getMembers
.and.returnValue(of(yourDesiredValueHere));