Angular 单元测试 - 模拟 REST 服务调用
Angular Unit Testing - Mocking a REST service call
我正在为 Angular 应用程序编写单元测试以测试前端功能,并尝试生成一种方法来模拟以下场景的休息服务调用:
我有一个class定义如下:
import { Component, OnInit } from '@angular/core';
import {RestService} from "../../../../../services/rest.service";
import {ActivatedRoute, Router} from "@angular/router";
@Component({
selector: 'app-example-class’,
templateUrl: ‘./example-class.component.html',
styleUrls: [‘./example-class.component.scss']
})
export class ExampleClass implements OnInit {
myData: any = [];
reloadInterval: any;
constructor(private rest: RestService) {
this.reloadInterval = setInterval(() => {
this.getData();
}, 10000);
}
ngOnInit() {
this.getData();
}
ngOnDestroy(){
clearInterval(this.reloadInterval);
}
getData() {
this.rest.call(‘exampleClass’, this.rest.id).subscribe((data: {}) => {
if (data['rows']) {
this.myData = data['rows'].reduce((accumulator, currRow)=> accumulator + currRow.value, 0);
}
});
}
}
我想使用 Karma/Jasmine 单元测试框架专门测试我的 "getData()" 方法。这是我创建的:
describe(‘ExampleClassComponent', () => {
let component: ExampleClass;
let fixture: ComponentFixture<ExampleClass>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
],
declarations: [ ExampleClass ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExampleClass);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create',
inject(
[HttpTestingController],
(httpMock: HttpTestingController) => {
expect(component).toBeTruthy();
}));
});
这行得通。组件被创建并且测试通过。但是,当我尝试执行以下操作时:
it('should test number of elements', ()=>{
component.getData();
expect(component.myData.length).toBe(1);
});
这失败了。它失败了,因为它试图通过对不是 运行 的服务的剩余调用来调用 getData() 方法。我想以某种方式模拟在该函数中进行的其余调用。我试过在我的测试 class 中创建一个 MockRestService class 是这样的:
class MockRestService extends RestService {
myData = [
{myData: 1}
];
call(endpoint: string, params?: Object, data?: any, queryString?: string, isCustomUri?: boolean): Observable<any> {
return of(this.myData);
}
}
然后修改我的测试:
it('should test number of elements', ()=>{
let mockRestService = new MockRestService(null);
component = new ExampleClass(mockRestService);
component.getData();
expect(component.myData.length).toBe(1);
});
但这不起作用。是否可以模拟 getData 中进行的其余调用以进行测试,如果可以,如何模拟?非常感谢您的帮助!
您不需要单独的 MockRestService
class 但可以使用 Jasmine 的 spyOn
来模拟 RestService.call
方法。这可能如下所示。
it('should test number of elements', ()=> {
// given
const restService = TestBed.inject(RestService);
const data = {} // define your rest call data
spyOn(restService, 'call').and.returnValue(of(data));
// when
component.getData();
// then
expect(component.myData.length).toBe(1);
});
我正在为 Angular 应用程序编写单元测试以测试前端功能,并尝试生成一种方法来模拟以下场景的休息服务调用:
我有一个class定义如下:
import { Component, OnInit } from '@angular/core';
import {RestService} from "../../../../../services/rest.service";
import {ActivatedRoute, Router} from "@angular/router";
@Component({
selector: 'app-example-class’,
templateUrl: ‘./example-class.component.html',
styleUrls: [‘./example-class.component.scss']
})
export class ExampleClass implements OnInit {
myData: any = [];
reloadInterval: any;
constructor(private rest: RestService) {
this.reloadInterval = setInterval(() => {
this.getData();
}, 10000);
}
ngOnInit() {
this.getData();
}
ngOnDestroy(){
clearInterval(this.reloadInterval);
}
getData() {
this.rest.call(‘exampleClass’, this.rest.id).subscribe((data: {}) => {
if (data['rows']) {
this.myData = data['rows'].reduce((accumulator, currRow)=> accumulator + currRow.value, 0);
}
});
}
}
我想使用 Karma/Jasmine 单元测试框架专门测试我的 "getData()" 方法。这是我创建的:
describe(‘ExampleClassComponent', () => {
let component: ExampleClass;
let fixture: ComponentFixture<ExampleClass>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
HttpClientTestingModule,
],
declarations: [ ExampleClass ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ExampleClass);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create',
inject(
[HttpTestingController],
(httpMock: HttpTestingController) => {
expect(component).toBeTruthy();
}));
});
这行得通。组件被创建并且测试通过。但是,当我尝试执行以下操作时:
it('should test number of elements', ()=>{
component.getData();
expect(component.myData.length).toBe(1);
});
这失败了。它失败了,因为它试图通过对不是 运行 的服务的剩余调用来调用 getData() 方法。我想以某种方式模拟在该函数中进行的其余调用。我试过在我的测试 class 中创建一个 MockRestService class 是这样的:
class MockRestService extends RestService {
myData = [
{myData: 1}
];
call(endpoint: string, params?: Object, data?: any, queryString?: string, isCustomUri?: boolean): Observable<any> {
return of(this.myData);
}
}
然后修改我的测试:
it('should test number of elements', ()=>{
let mockRestService = new MockRestService(null);
component = new ExampleClass(mockRestService);
component.getData();
expect(component.myData.length).toBe(1);
});
但这不起作用。是否可以模拟 getData 中进行的其余调用以进行测试,如果可以,如何模拟?非常感谢您的帮助!
您不需要单独的 MockRestService
class 但可以使用 Jasmine 的 spyOn
来模拟 RestService.call
方法。这可能如下所示。
it('should test number of elements', ()=> {
// given
const restService = TestBed.inject(RestService);
const data = {} // define your rest call data
spyOn(restService, 'call').and.returnValue(of(data));
// when
component.getData();
// then
expect(component.myData.length).toBe(1);
});