Angular2/RxJS/Jasmine:如何测试可观察链/序列(操作符)

Angular2/RxJS/Jasmine:如何测试可观察链/序列(操作符),angular,unit-testing,jasmine,rxjs,observable,Angular,Unit Testing,Jasmine,Rxjs,Observable,作为Angular 4项目的一部分,我正在拼命尝试使用Jasmine测试一个函数,该函数使用操作符实现RxJs链/序列(map) 类集合分解器{ 搜索会合(代码:字符串):可观察{ 返回可观察的。创建(观察者=>{ this.userCardService.readCard(code).map(userData=>{ 这个.rendezVousService.search(userData.subscribe)( 结果=>{ 下一步(结果); }, 错误=>{ 观察者错误(错误); } ); }

作为Angular 4项目的一部分,我正在拼命尝试使用Jasmine测试一个函数,该函数使用操作符实现RxJs链/序列(
map

类集合分解器{
搜索会合(代码:字符串):可观察{
返回可观察的。创建(观察者=>{
this.userCardService.readCard(code).map(userData=>{
这个.rendezVousService.search(userData.subscribe)(
结果=>{
下一步(结果);
},
错误=>{
观察者错误(错误);
}
);
});
});
}
}
我的单元测试使用2个模拟来“模拟”2个服务层:
userCardService
rendezVousService

类MockUserCardService{
读卡(代码:字符串):可观察{
可观察的回报率(“”);
}
}
类集合服务{
搜索(userData:string):可观察{
可观测收益({
RDV:[]
});
}
}
在每个之前(()=>{
TestBed.configureTestingModule({
供应商:[
会合分解器,
{provide:RendezVousService,useClass:MockRendezVousService},
{提供:SWCVitalerReadingService,useClass:MockSWCVitalerReadingService}
]
});
fixture=TestBed.get(集合解析器);
});
这里是我的单元测试

it('should return the expected response',async(()=>{
fixture.resolve(未定义,未定义).subscribe(
rdvs=>{
console.log(“expect”);
期望值(rdvs).toEqual({
RDV:[]
});
},
错误=>{
控制台日志(“失败”);
失败(“预计不会出现错误”);
}
);
}));
当我执行它时,测试似乎不会等待模拟可观察对象发出的事件。既不执行
预期的
,也不执行
失败的
。我确信这一点,因为控制台中没有任何日志记录

我发现要通过此测试的唯一方法是不使用操作符
map
,而是用嵌套订阅替换我的代码

搜索会合(代码:字符串):可观察{ 返回可观察的。创建(观察者=>{ 此.userCardService.readCard(代码).subscribe( 用户数据=>{ 这个.rendezVousService.search(userData.subscribe)( rdvs=>{ 下一个观察者(rdvs); }, 错误=>{ 观察者错误(错误); } ) }, 错误=>{ 观察者错误(错误); } ); }); } 除了
map
(例如
zip
)之外,我还遇到了与其他操作符相同的问题


感谢您的帮助。

您可以通过交换可观察的
来简化您的
集合解析器
。为RxJs中的现有行为/功能创建

类集合分解器{
搜索会合(代码:字符串):可观察{
返回此.userCardService.readCard(代码)
.mergeMap(userData=>this.rendezVousService.search(userData));
}
}
这样一来,你就没有那么多的边缘案例需要抓住

通过将
读卡
搜索
与返回
Rx.Observable.from([])
的模拟数据交换,可以在没有时间的情况下完成测试。只需在
searchRendezVous()
上调用
.toPromise()
,就可以在没有任何调度程序魔法的情况下实现这一点

it('返回数据',()=>{
返回搜索集合('foo')
.toPromise()
。然后(搜索结果=>{
expect(searchResults).to.not.be.empty();//断言所需内容
})
});

您可以通过交换可观察的
来简化您的
集合解析程序
。为RxJs中的现有行为/功能创建

类集合分解器{
搜索会合(代码:字符串):可观察{
返回此.userCardService.readCard(代码)
.mergeMap(userData=>this.rendezVousService.search(userData));
}
}
这样一来,你就没有那么多的边缘案例需要抓住

通过将
读卡
搜索
与返回
Rx.Observable.from([])
的模拟数据交换,可以在没有时间的情况下完成测试。只需在
searchRendezVous()
上调用
.toPromise()
,就可以在没有任何调度程序魔法的情况下实现这一点

it('返回数据',()=>{
返回搜索集合('foo')
.toPromise()
。然后(搜索结果=>{
expect(searchResults).to.not.be.empty();//断言所需内容
})
});

看看这个与测试无关的问题,但是您对
Observable.create的调用是反模式的。您可能需要考虑以下操作:当您有许多异步操作时最简单的方法是使用完成函数,寻找Jasmin。在这两个页面上完成的模拟类返回一些数据而不是<代码>空对象< /代码>查看与测试无关的内容,但是,您对
Observable.create
的调用是一种反模式。您可能需要考虑以下操作:当您有许多异步操作时最简单的方法是使用完成函数,查找Jasmin。在这两个页面上完成的模拟类返回一些数据而不是<代码>空对象< /代码>