Angular2/RxJS/Jasmine:如何测试可观察链/序列(操作符)
作为Angular 4项目的一部分,我正在拼命尝试使用Jasmine测试一个函数,该函数使用操作符实现RxJs链/序列(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)( 结果=>{ 下一步(结果); }, 错误=>{ 观察者错误(错误); } ); }
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。在这两个页面上完成的模拟类返回一些数据而不是<代码>空对象< /代码>