微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

单元测试 – 单元测试Angular 2中的可观察量

在Angular 2中单元测试返回Observable结果的服务的正确方法是什么?假设我们在CarService服务类中有一个getCars方法
...
export class CarService{
    ...
    getCars():Observable<any>{
        return this.http.get("http://someurl/cars").map( res => res.json() );
    }
    ...
}

如果我尝试按以下方式编写测试,我会收到警告:“SPEC没有预期”:

it('retrieves all the cars',inject( [CarService],( carService ) => {
     carService.getCars().subscribe( result => {         
         expect(result.length).toBeGreaterThan(0);
     } );       
}) );

使用injectAsync没有帮助,因为就我所见,它与Promise对象一起使用。

Angular的正确方法(第2版):
it('retrieves all the cars',async(inject( [CarService],( carService ) => {
     carService.getCars().subscribe(result => expect(result.length).toBeGreaterThan(0)); 
}));

Async Observables与Sync Observables

重要的是要理解Observable可以是同步的也可以是异步的。

在您的特定示例中,Observable是异步的(它包装了一个http调用)。
因此,您必须使用async函数在特殊的异步测试区域中执行其体内的代码。它拦截并跟踪其主体中创建的所有承诺,从而可以在完成异步操作时期望测试结果。

但是,如果您的Observable是同步的,例如:

...
export class CarService{
    ...
    getCars():Observable<any>{
        return Observable.of(['car1','car2']);
    }
    ...

你不需要异步功能,你的测试就会变得简单

it('retrieves all the cars',( carService ) => {
     carService.getCars().subscribe(result => expect(result.length).toBeGreaterThan(0)); 
});

大理石

另一方面,一般情况下测试Observable和Angular时需要考虑的是marble testing

你的例子很简单,但通常逻辑比调用http服务更复杂,测试这个逻辑变得很头疼。
弹珠使测试非常简短,全面(对于测试ngrx effects特别有用)。

如果您使用Jasmine,您可以使用jasmine-marbles,对于Jest,有jest-marbles,但如果您更喜欢其他内容,则有rxjs-marbles,它应该与任何测试框架兼容。

Here是用弹珠复制和修复比赛条件的一个很好的例子。

Official guide for testing

原文地址:https://www.jb51.cc/angularjs/144056.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐