【发布时间】:2017-07-17 08:05:34
【问题描述】:
作为 Angular 4 项目的一部分,我正在拼命地尝试用 Jasmine 测试一个函数,该函数使用运算符实现 RxJs 链/序列(在我的例子中为map)。
class RendezVousResolver {
searchRendezVous(code: string): Observable<any> {
return Observable.create(observer => {
this.userCardService.readCard(code).map(userData => {
this.rendezVousService.search(userData).subscribe(
result => {
observer.next(result);
},
error => {
observer.error(error);
}
);
});
});
}
}
我的单元测试使用 2 个模拟来“模拟”两个服务层:userCardService 和 rendezVousService。
class MockUserCardService {
readCard(code: string): Observable<any> {
return Observable.of('<data></data>');
}
}
class MockRendezVousService {
search(userData : string): Observable<any> {
return Observable.of({
rdvs: []
});
}
}
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
RendezVousResolver,
{ provide: RendezVousService, useClass: MockRendezVousService },
{ provide: SwcVitaleReadingService, useClass: MockSwcVitaleReadingService }
]
});
fixture = TestBed.get(RendezVousResolver);
});
这里是我的单元测试。
it('should return the expected response', async(() => {
fixture.resolve(undefined, undefined).subscribe(
rdvs => {
console.log("expect");
expect(rdvs).toEqual({
rdvs: []
});
},
error => {
console.log("fail");
fail('No error was expected');
}
);
}));
当我执行它时,测试似乎没有等待被模拟的 Observable 发出的事件。 expected 和 fail 均未执行。我很确定,因为控制台中没有记录任何内容。
我发现使此测试通过的唯一方法是不使用运算符 map 并将我的代码替换为嵌套订阅。
searchRendezVous(code: string): Observable<any> {
return Observable.create(observer => {
this.userCardService.readCard(code).subscribe(
userData => {
this.rendezVousService.search(userData).subscribe(
rdvs => {
observer.next(rdvs);
},
error => {
observer.error(error);
}
)
},
error => {
observer.error(error);
}
);
});
}
除了map(例如zip)以外的其他运营商,我也遇到了同样的问题。
感谢您的帮助。
【问题讨论】:
-
与测试无关,但是您对
Observable.create的调用是一种反模式。您可能需要考虑观看以下内容:egghead.io/courses/… -
当你有许多异步操作时,最简单的方法是使用 done 函数,在这个页面上查找 jasmine.done angular.io/guide/testing
-
在两个模拟类中都返回一些数据而不是
empty object
标签: angular unit-testing jasmine rxjs observable