单元测试 Angular 可观察量
Unit Testing Angular Observables
我是测试领域的新手,我刚刚开始为现有 Angular 2 代码编写单元测试。我有一个函数 confirmDelete
returns Obserable<boolean>
并在内部使用 PrimeNG 的 ConfirmationService
来获取用户对弹出窗口的反馈。
函数定义如下:
confirmDelete(): Observable<boolean> {
let confirmObservable = Observable.create((observer: Observer<boolean>) => {
this.confirmationService.confirm({
header: 'Delete Confirmation',
message: 'Do you really want to delete this record?',
accept: () => {
observer.next(true);
observer.complete();
},
reject: () => {
observer.next(false);
observer.complete();
}
});
});
return confirmObservable;
}
我想为这段代码写一个单元测试。我计划为 ConfirmationService
编写一个存根,但因为我是单元测试领域的新手,所以我发现设置这些东西很困难。
我的问题是在此特定场景中编写单元测试的正确方法是什么。
编辑:-
我尝试了@peeskillet 提出的解决方案,但后来我开始收到 ConfirmationService
和 MockConfirmationService
之间的类型不匹配错误。
下面是在 PrimeNG 库中找到的 ConfirmationService
和 Confirmation
类 的声明。
export interface Confirmation {
message: string;
icon?: string;
header?: string;
accept?: Function;
reject?: Function;
acceptVisible?: boolean;
rejectVisible?: boolean;
acceptEvent?: EventEmitter<any>;
rejectEvent?: EventEmitter<any>;
}
export declare class ConfirmationService {
private requireConfirmationSource;
private acceptConfirmationSource;
requireConfirmation$: Observable<Confirmation>;
accept: Observable<Confirmation>;
confirm(confirmation: Confirmation): this;
onAccept(): void;
}
我可能会让模拟保留 accept
和 reject
函数的引用。然后在测试中您可以调用它们来检查它们是否发出正确的布尔值。像
class MockConfirmationService {
accept: Function;
reject: Function;
confirm(config: any) {
this.accept = config.accept;
this.reject = config.reject;
}
}
然后在您的测试中只需调用 accept
来测试 true
是否发出,并调用 reject
来测试 false
是否被发出。
describe('serivce: ModalService', () => {
let modalService: ModalService;
let confirmService: MockConfirmationService;
beforeEach(() => {
confirmService = new MockConfirmationService();
TestBed.configureTestingModule({
providers: [
ModalService,
{ provide: ConfirmationService, useValue: confirmService }
]
});
modalService = TestBed.get(ModalService);
});
it('should return true when accepted', async(() => {
modalService.confirmDelete().subscribe(result => {
expect(result).toBe(true);
console.log('accepted test complete');
});
confirmService.accept();
}));
it('should return false when rejected', async(() => {
modalService.confirmDelete().subscribe(result => {
expect(result).toBe(false);
console.log('rejected test complete');
});
confirmService.reject();
}));
});
我已经建立了 peeskillet 的答案。 p-confirmDialog 组件调用服务的订阅,所以我不得不添加 requireConfirmationSource,这是我在 PrimeNg 源代码中找到的。我的模拟如下:
//
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
//
export class ConfirmationServiceMock {
public key: string = 'mock1';
public header: string = 'Delete Confirmation';
public icon: string = '';
public message: string = '';
// Call Accept to emulate a user accepting
public accept: Function;
// Call Reject to emulate a user rejecting
public reject: Function;
private requireConfirmationSource = new Subject<any>();
requireConfirmation$ = this.requireConfirmationSource.asObservable();
//
public confirm(config: any) {
console.log( 'In confirm service mock...' );
this.message = config.message;
this.accept = config.accept;
this.reject = config.reject;
console.log( this.message );
return this;
}
}
//
我是测试领域的新手,我刚刚开始为现有 Angular 2 代码编写单元测试。我有一个函数 confirmDelete
returns Obserable<boolean>
并在内部使用 PrimeNG 的 ConfirmationService
来获取用户对弹出窗口的反馈。
函数定义如下:
confirmDelete(): Observable<boolean> {
let confirmObservable = Observable.create((observer: Observer<boolean>) => {
this.confirmationService.confirm({
header: 'Delete Confirmation',
message: 'Do you really want to delete this record?',
accept: () => {
observer.next(true);
observer.complete();
},
reject: () => {
observer.next(false);
observer.complete();
}
});
});
return confirmObservable;
}
我想为这段代码写一个单元测试。我计划为 ConfirmationService
编写一个存根,但因为我是单元测试领域的新手,所以我发现设置这些东西很困难。
我的问题是在此特定场景中编写单元测试的正确方法是什么。
编辑:-
我尝试了@peeskillet 提出的解决方案,但后来我开始收到 ConfirmationService
和 MockConfirmationService
之间的类型不匹配错误。
下面是在 PrimeNG 库中找到的 ConfirmationService
和 Confirmation
类 的声明。
export interface Confirmation {
message: string;
icon?: string;
header?: string;
accept?: Function;
reject?: Function;
acceptVisible?: boolean;
rejectVisible?: boolean;
acceptEvent?: EventEmitter<any>;
rejectEvent?: EventEmitter<any>;
}
export declare class ConfirmationService {
private requireConfirmationSource;
private acceptConfirmationSource;
requireConfirmation$: Observable<Confirmation>;
accept: Observable<Confirmation>;
confirm(confirmation: Confirmation): this;
onAccept(): void;
}
我可能会让模拟保留 accept
和 reject
函数的引用。然后在测试中您可以调用它们来检查它们是否发出正确的布尔值。像
class MockConfirmationService {
accept: Function;
reject: Function;
confirm(config: any) {
this.accept = config.accept;
this.reject = config.reject;
}
}
然后在您的测试中只需调用 accept
来测试 true
是否发出,并调用 reject
来测试 false
是否被发出。
describe('serivce: ModalService', () => {
let modalService: ModalService;
let confirmService: MockConfirmationService;
beforeEach(() => {
confirmService = new MockConfirmationService();
TestBed.configureTestingModule({
providers: [
ModalService,
{ provide: ConfirmationService, useValue: confirmService }
]
});
modalService = TestBed.get(ModalService);
});
it('should return true when accepted', async(() => {
modalService.confirmDelete().subscribe(result => {
expect(result).toBe(true);
console.log('accepted test complete');
});
confirmService.accept();
}));
it('should return false when rejected', async(() => {
modalService.confirmDelete().subscribe(result => {
expect(result).toBe(false);
console.log('rejected test complete');
});
confirmService.reject();
}));
});
我已经建立了 peeskillet 的答案。 p-confirmDialog 组件调用服务的订阅,所以我不得不添加 requireConfirmationSource,这是我在 PrimeNg 源代码中找到的。我的模拟如下:
//
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
//
export class ConfirmationServiceMock {
public key: string = 'mock1';
public header: string = 'Delete Confirmation';
public icon: string = '';
public message: string = '';
// Call Accept to emulate a user accepting
public accept: Function;
// Call Reject to emulate a user rejecting
public reject: Function;
private requireConfirmationSource = new Subject<any>();
requireConfirmation$ = this.requireConfirmationSource.asObservable();
//
public confirm(config: any) {
console.log( 'In confirm service mock...' );
this.message = config.message;
this.accept = config.accept;
this.reject = config.reject;
console.log( this.message );
return this;
}
}
//