Jasmine unit tests - TypeError: Cannot read properties of undefined (reading 'pipe')
Jasmine unit tests - TypeError: Cannot read properties of undefined (reading 'pipe')
TypeError: Cannot read properties of undefined (reading 'pipe') at MyComponent.fetchData
我在 Angular
中 运行 我的 Jasmine
单元测试时遇到上述错误。现有 beforeEach
不喜欢我在 my.component.ts
的 ngOnInit()
中的新 fetchData
功能。我在本规范中的所有六个测试都因相同的错误而失败。有什么想法吗?
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
});
您的组件需要 getData()
到 return 一个可观察对象,然后向其添加一个 .pipe(...)
。默认情况下,间谍对象方法 return undefined
。您需要将函数模拟为 return 值
const myServiceObj = jasmine.createSpyObj('myService', [
'selectType',
'getData',
]);
您也可以模拟 return 值
myServiceObj.getData
.and
.returnValue(of(true));
TypeError: Cannot read properties of undefined (reading 'pipe') at MyComponent.fetchData
我在 Angular
中 运行 我的 Jasmine
单元测试时遇到上述错误。现有 beforeEach
不喜欢我在 my.component.ts
的 ngOnInit()
中的新 fetchData
功能。我在本规范中的所有六个测试都因相同的错误而失败。有什么想法吗?
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
});
您的组件需要 getData()
到 return 一个可观察对象,然后向其添加一个 .pipe(...)
。默认情况下,间谍对象方法 return undefined
。您需要将函数模拟为 return 值
const myServiceObj = jasmine.createSpyObj('myService', [
'selectType',
'getData',
]);
您也可以模拟 return 值
myServiceObj.getData
.and
.returnValue(of(true));