如何使用可观察服务测试组件错误处理
How to test component error handling with observable service
上下文
我正在尝试测试一个组件。在另一个 post 中,我询问了有关测试直接函数调用的问题。在这里,我使用相同的示例组件专注于我的组件的错误处理。
我想测试,当我的服务 returns 出现可观察到的错误时,我的组件是否正确调用 console.error(error)。
如何 "create" 此错误触发并测试我的组件是否正确处理它。我听说间谍可以做到这一点,但我不知道在哪里设置这个间谍。
我想模拟服务上的 http 请求可能失败的情况。由于任何原因或任何错误代码。
代码
这是组件、存根服务和我的规范文件的代码。
组件
import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { UserManagementService } from '../../shared/services/global.api';
import { UserListItemComponent } from './user-list-item.component';
@Component({
selector: 'app-user-list',
templateUrl: './user-list.component.html'
})
export class UserListComponent implements OnInit {
public userList = [];
constructor(
private _userManagementService: UserManagementService,
) { }
ngOnInit() {
this.getUserList();
}
onRefreshUserList() {
this.getUserList();
}
getUserList(notifyWhenComplete = false) {
this._userManagementService.getListUsers().subscribe(
result => {
this.userList = result.objects;
},
error => {
console.error(error); // That's the part of my component I want to test
},
() => {
if (notifyWhenComplete) {
console.info('Notification');
}
}
);
}
}
组件规范文件
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
async,
fakeAsync,
ComponentFixture,
TestBed,
tick,
inject
} from '@angular/core/testing';
import { Observable } from 'rxjs/Observable';
// Components
import { UserListComponent } from './user-list.component';
// Services
import { UserManagementService } from '../../shared/services/global.api';
import { UserManagementServiceStub } from '../../testing/services/global.api.stub';
let comp: UserListComponent;
let fixture: ComponentFixture<UserListComponent>;
let service: UserManagementService;
describe('UserListComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [UserListComponent],
imports: [],
providers: [
{
provide: UserManagementService,
useClass: UserManagementServiceStub
}
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
}));
tests();
});
function tests() {
beforeEach(() => {
fixture = TestBed.createComponent(UserListComponent);
comp = fixture.componentInstance;
service = TestBed.get(UserManagementService);
});
it(`should be initialized`, () => {
expect(fixture).toBeDefined();
expect(comp).toBeDefined();
});
it(`should get the user List after ngOnInit`, async(() => {
fixture.detectChanges();
expect(comp.userList.length).toBe(3, 'user list exists after init');
}));
}
存根服务
import { Observable } from 'rxjs/Observable';
export class UserManagementServiceStub {
getListUsers() {
return Observable.from([
{
count: 3,
objects:
[
{
id: "7f5a6610-f59b-4cd7-b649-1ea3cf72347f",
name: "user 1",
group: "any"
},
{
id: "d6f54c29-810e-43d8-8083-0712d1c412a3",
name: "user 2",
group: "any"
},
{
id: "2874f506-009a-4af8-8ca5-f6e6ba1824cb",
name: "user 3",
group: "any"
}
]
}
]);
}
}
如果我的理解是正确的,您只需要一种方法来 return 来自存根服务的错误,您可以创建一个单独的存根,其中 return 是一个 Observable 错误,并且然后在检查错误处理的测试中使用它:
export class UserManagementServiceErrorStub {
getListUsers() {
return Observable.throw(new Error('Test error'));
}
}
这里有一篇关于使用 Observables 测试 Angular 服务的非常好的文章:
https://web.archive.org/web/20191214083526/http://www.zackarychapple.guru/angular2/2016/11/25/angular2-testing-services.html
更新 - 01/06/2019 用于 RxJS 6
import { throwError } from 'rxjs';
class UserManagementServiceErrorStub {
getListUsers() {
return throwError(new Error('Test error'));
}
}
上下文
我正在尝试测试一个组件。在另一个 post 中,我询问了有关测试直接函数调用的问题。在这里,我使用相同的示例组件专注于我的组件的错误处理。
我想测试,当我的服务 returns 出现可观察到的错误时,我的组件是否正确调用 console.error(error)。
如何 "create" 此错误触发并测试我的组件是否正确处理它。我听说间谍可以做到这一点,但我不知道在哪里设置这个间谍。
我想模拟服务上的 http 请求可能失败的情况。由于任何原因或任何错误代码。
代码
这是组件、存根服务和我的规范文件的代码。
组件
import { Component, OnInit, ViewContainerRef } from '@angular/core';
import { UserManagementService } from '../../shared/services/global.api';
import { UserListItemComponent } from './user-list-item.component';
@Component({
selector: 'app-user-list',
templateUrl: './user-list.component.html'
})
export class UserListComponent implements OnInit {
public userList = [];
constructor(
private _userManagementService: UserManagementService,
) { }
ngOnInit() {
this.getUserList();
}
onRefreshUserList() {
this.getUserList();
}
getUserList(notifyWhenComplete = false) {
this._userManagementService.getListUsers().subscribe(
result => {
this.userList = result.objects;
},
error => {
console.error(error); // That's the part of my component I want to test
},
() => {
if (notifyWhenComplete) {
console.info('Notification');
}
}
);
}
}
组件规范文件
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
async,
fakeAsync,
ComponentFixture,
TestBed,
tick,
inject
} from '@angular/core/testing';
import { Observable } from 'rxjs/Observable';
// Components
import { UserListComponent } from './user-list.component';
// Services
import { UserManagementService } from '../../shared/services/global.api';
import { UserManagementServiceStub } from '../../testing/services/global.api.stub';
let comp: UserListComponent;
let fixture: ComponentFixture<UserListComponent>;
let service: UserManagementService;
describe('UserListComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [UserListComponent],
imports: [],
providers: [
{
provide: UserManagementService,
useClass: UserManagementServiceStub
}
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
}));
tests();
});
function tests() {
beforeEach(() => {
fixture = TestBed.createComponent(UserListComponent);
comp = fixture.componentInstance;
service = TestBed.get(UserManagementService);
});
it(`should be initialized`, () => {
expect(fixture).toBeDefined();
expect(comp).toBeDefined();
});
it(`should get the user List after ngOnInit`, async(() => {
fixture.detectChanges();
expect(comp.userList.length).toBe(3, 'user list exists after init');
}));
}
存根服务
import { Observable } from 'rxjs/Observable';
export class UserManagementServiceStub {
getListUsers() {
return Observable.from([
{
count: 3,
objects:
[
{
id: "7f5a6610-f59b-4cd7-b649-1ea3cf72347f",
name: "user 1",
group: "any"
},
{
id: "d6f54c29-810e-43d8-8083-0712d1c412a3",
name: "user 2",
group: "any"
},
{
id: "2874f506-009a-4af8-8ca5-f6e6ba1824cb",
name: "user 3",
group: "any"
}
]
}
]);
}
}
如果我的理解是正确的,您只需要一种方法来 return 来自存根服务的错误,您可以创建一个单独的存根,其中 return 是一个 Observable 错误,并且然后在检查错误处理的测试中使用它:
export class UserManagementServiceErrorStub {
getListUsers() {
return Observable.throw(new Error('Test error'));
}
}
这里有一篇关于使用 Observables 测试 Angular 服务的非常好的文章: https://web.archive.org/web/20191214083526/http://www.zackarychapple.guru/angular2/2016/11/25/angular2-testing-services.html
更新 - 01/06/2019 用于 RxJS 6
import { throwError } from 'rxjs';
class UserManagementServiceErrorStub {
getListUsers() {
return throwError(new Error('Test error'));
}
}