'Cannot read properties of undefined (reading 'subscribe') in Unit Test NgOnInIt
I tried a lot of SO Question's answers but nothing worked for this.so in mt test im doing something like this.
const stubStudentService = jasmine.createSpyObj('StudentsCrudService',['getAllStudents','updateStudent']);
const stubWebSocketService = jasmine.createSpyObj('WebsocketService',['getNotified']);
describe('StudentsListComponent', () => {
let component: StudentsListComponent;
let fixture: ComponentFixture<StudentsListComponent>;;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [StudentsListComponent],
imports: [],
providers: [
{ provide: StudentsCrudService, useValue: stubStudentService },
{ provide: WebsocketService, useValue: stubWebSocketService },
NotificationService,
],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(StudentsListComponent);
stubStudentService.getAllStudents.and.returnValue(of(studentPayload));
stubWebSocketService.getNotified.and.returnValue(of('success'));
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
In my component, it look like this
constructor(
private studentService: StudentsCrudService,
private notificationService: NotificationService,
private webSocketNotifier: WebsocketService
) {}
ngOnInit(): void {
this.studentSubscription();
this.webSocketSubscription();
}
studentSubscription() {
this.studentQueryRef = this.studentService
.getAllStudents()
this.initSubscription.add(
this.studentQueryRef
.valueChanges.subscribe((response) => {
this.paginatedStudents = {...response.data.paginateStudents}
})
);
}
When I run the test im getting Cannot read properties of undefined (reading 'subscribe') at StudentsListComponent.studentSubscription. I tried so many things but nothing worked.
Solution 1:[1]
The first fixture.detectChanges is when ngOnInit is called.
You have mocked studentService correctly but you haven't mocked the return of getAllStudents incorrectly.
Try this (follow comments with !!):
const stubStudentService = jasmine.createSpyObj('StudentsCrudService',['getAllStudents','updateStudent']);
const stubWebSocketService = jasmine.createSpyObj('WebsocketService',['getNotified']);
describe('StudentsListComponent', () => {
let component: StudentsListComponent;
let fixture: ComponentFixture<StudentsListComponent>;
// !! make the following changes
let stubStudentService: jasmine.SpyObj<StudentCrudService>;
let stubWebSocketService: jasmine.SpyObj<WebsocketService>;
beforeEach(async () => {
// !! assign the spies in a beforeEach so they are fresh for every test
stubStudentService = jasmine.createSpyObj('StudentsCrudService',
['getAllStudents','updateStudent']);
stubWebSocketService = jasmine.createSpyObj('WebsocketService',
['getNotified']);
await TestBed.configureTestingModule({
declarations: [StudentsListComponent],
imports: [],
providers: [
{ provide: StudentsCrudService, useValue: stubStudentService },
{ provide: WebsocketService, useValue: stubWebSocketService },
NotificationService,
],
}).compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(StudentsListComponent);
// !! change below to return object of valueChanges
stubStudentService.getAllStudents.and.returnValue({ valueChanges: of(studentPayload) });
stubWebSocketService.getNotified.and.returnValue(of('success'));
component = fixture.componentInstance;
// !! the below fixture.detectChanges will call ngOnInit
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
The above should hopefully fix your problem.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | AliF50 |
