gpt4 book ai didi

unit-testing - 对 Angular 2 中的可观察对象进行单元测试

转载 作者:太空狗 更新时间:2023-10-29 16:47:22 25 4
gpt4 key购买 nike

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

...
export class CarService{
...
getCars():Observable<any>{
return this.http.get("http://someurl/cars").map( res => res.json() );
}
...
}

如果我尝试按以下方式编写测试,我会收到警告:“SPEC HAS NO EXPECTATIONS”:

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', waitForAsync(inject([CarService], (carService) => {
carService.getCars().subscribe(result => expect(result.length).toBeGreaterThan(0));
}));

异步 Observable 与同步 Observable

了解 Observable 可以是同步的或异步的很重要。

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

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

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

您不需要waitForAsync 函数,您的测试将变得简单

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

弹珠

在一般测试 Observables 和特别是 Angular 时要考虑的另一件事是 marble testing .

您的示例非常简单,但通常逻辑比仅调用 http 服务更复杂,并且测试此逻辑变得令人头疼。
弹珠使测试变得非常简短、简单和全面(它对测试 ngrx effects 尤其有用)。

如果您使用的是 Jasmine,则可以使用 jasmine-marbles , 对于 Jestjest-marbles , 但如果你喜欢别的东西,有 rxjs-marbles ,它应该与任何测试框架兼容。

Here是使用弹珠重现和修复竞争条件的一个很好的例子。


Official guide for testing

关于unit-testing - 对 Angular 2 中的可观察对象进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34607990/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com