当前位置:  开发笔记 > 前端 > 正文

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

如何解决《单元测试Angular2中的可观察量》经验,为你挑选了3个好方法。

在Angular 2中单元测试返回Observable结果的服务的正确方法是什么?假设我们在CarService服务类中有一个getCars方法:

...
export class CarService{
    ...
    getCars():Observable{
        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我所见,它可以与对象一起使用.



1> JeB..:

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{
        return Observable.of(['car1', 'car2']);
    }
    ...

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

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

大理石

在测试Observables时特别考虑的另一件事是Angular,特别是Angular 测试.

您的示例非常简单,但通常逻辑比调用http服务更复杂,并且测试此逻辑变得令人头疼.
弹珠使测试非常简短,全面(对于测试ngrx效果特别有用).

如果你正在使用Jasmine你可以使用jasmine-marbles,因为它Jest有jest- marbles,但如果你喜欢别的东西,那就是rxjs-marbles,它应该与任何测试框架兼容.

这是用大理石复制和修复竞争条件的一个很好的例子.


官方测试指南


因此,我发现如果执行此操作,则稍后再指定另一个测试,这取决于在另一个测试的订阅中运行的测试的顺序是否仍处于活动状态。解决这个问题的正确方法是什么?在lambda函数结束时退订?

2> Erdinc Guzel..:

最后,我以一个有效的例子结束.Observableclass有一个方法toPromise,它将Observable转换为Promise对象.正确的方法应该是:

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

但是,虽然上面的代码适用于任何Observable对象,我仍然有Observable从Http请求返回的s 的问题,这可能是一个错误.这是一个展示上述案例的傻瓜:http://plnkr.co/edit/ak2qZH685QzTN6RoK71H?p =preview

更新:
从版本beta.14开始,它似乎与提供的解决方案一起正常工作.



3> Marcus..:

https://angular.io/guide/testing当前显示了几种方法。这是一个:

it('#getObservableValue should return value from observable',
    (done: DoneFn) => {
       service.getObservableValue().subscribe(value => {
       expect(value).toBe('observable value');
       done();
    });
});

推荐阅读
携手相约幸福
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有