TypeError: Cannot read properties of undefined (reading 'pipe') at MyComponent.fetchData
I'm getting the above error when running my Jasmine
unit tests in Angular
. Existing beforeEach
's don't like my new fetchData
function in my.component.ts
's ngOnInit()
. All six of my tests in this spec fail with the same error. Any ideas?
my.component.ts
export class MyComponent extends BaseComponent implements OnInit {
constructor(
private myService: MyService,
) {}
ngOnInit(): void {
this.fetchData();
}
public fetchData() {
this.myService.getData()
.pipe(takeUntil(this.unsubscribe$)).subscribe( //this.unsubscribe$ gets destroyed in BaseComponent's ngOnDestroy(). Only purpose of BaseComponent is to unsubscribe from observables
data => {
if (data) {
return this.myService.getTypesByCategory(data);
}
}
);
return;
}
my.service.ts
export class MyService {
getData(): Observable<any> {
return this.httpClient.get('https://myurl.com/myquerystring')
.pipe(this.showError());
}
getTypesByCategory(data) {
for (let region of data.regions) {
return this.selectType(myArg);
}
}
selectType(myArg): void {
// do stuff
}
}
my.component.spec.ts
import { ComponentFixture, TestBed, fakeAsync, tick, waitForAsync } from '@angular/core/testing';
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { of } from 'rxjs';
import { Router } from '@angular/router';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MyService } from 'src/app/my.service';
import { MyComponent } from './mycomponent';
describe('DeviceRegistrationComponent', () => {
let component: DeviceRegistrationComponent;
let fixture: ComponentFixture<DeviceRegistrationComponent>;
let routerSpy: jasmine.SpyObj<Router>;
let myServiceSpy: jasmine.SpyObj<MyService>;
beforeEach(
waitForAsync(() => {
const myServiceObj = jasmine.createSpyObj('myService', [
'selectType',
'getData',
]);
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
RouterTestingModule,
ReactiveFormsModule,
],
declarations: [MyComponent],
providers: [
FormBuilder,
{ provide: MyService, useValue: myServiceObj },
],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
routerSpy = TestBed.inject(Router) as jasmine.SpyObj<Router>;
myServiceSpy = TestBed.inject(MyService) as jasmine.SpyObj<MyService>;
}),
);
beforeEach(() => {
fixture = TestBed.createComponent(MyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
expect(myServiceSpy.selectType).toHaveBeenCalledWith(true);
});
// 5 more tests all fail with the same error
});
CodePudding user response:
Your component expects getData()
to return an observable that it then adds a .pipe(...)
to. By default the spy object methods return undefined
. You need to mock the functions to return values
const myServiceObj = jasmine.createSpyObj('myService', [
'selectType',
'getData',
]);
You can mock the return value too
myServiceObj.getData
.and
.returnValue(of(true));